diff --git a/.ci/build.sh b/.ci/build.sh index 38cd36c0c..f0d91fe18 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -1158,10 +1158,14 @@ EOF # Run appimage-builder in extract-and-run mode for Docker compatibility. # --appdir is a workaround for https://github.com/AppImageCrafters/appimage-builder/issues/270 - project="$project" project_id="$project_id" project_version="$project_version" project_icon="$project_icon" arch_deb="$arch_deb" \ - arch_appimage="$arch_appimage" appimage_path="$cwd/$package_name.AppImage" APPIMAGE_EXTRACT_AND_RUN=1 ./appimage-builder.AppImage \ - --recipe AppImageBuilder-generated.yml --appdir "$(grep -oP '^\s+path: \K(.+)' AppImageBuilder-generated.yml)" - status=$? + for retry in 1 2 3 4 5 + do + project="$project" project_id="$project_id" project_version="$project_version" project_icon="$project_icon" arch_deb="$arch_deb" \ + arch_appimage="$arch_appimage" appimage_path="$cwd/$package_name.AppImage" APPIMAGE_EXTRACT_AND_RUN=1 ./appimage-builder.AppImage \ + --recipe AppImageBuilder-generated.yml --appdir "$(grep -oP '^\s+path: \K(.+)' AppImageBuilder-generated.yml)" + status=$? + [ $status -eq 0 ] && break + done # Remove appimage-builder binary on failure, just in case it's corrupted. [ $status -ne 0 ] && rm -f "$appimage_builder_binary" diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index a91518084..ead4d5dcc 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -60,6 +60,7 @@ jobs: make ${{ matrix.environment.prefix }}-gcc ${{ matrix.environment.prefix }}-pkg-config + ${{ matrix.environment.prefix }}-openal ${{ matrix.environment.prefix }}-freetype ${{ matrix.environment.prefix }}-SDL2 ${{ matrix.environment.prefix }}-zlib diff --git a/.gitignore b/.gitignore index 267f3d766..b4c67ef0a 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,12 @@ RC* # Qt Creator CMakeLists.txt.user + +# Debian builder +/debian/*.log +/debian/*.substvars +/debian/.debhelper +/debian/86box +/debian/debhelper-build-stamp +/debian/files +/obj-*-linux-gnu diff --git a/CMakeLists.txt b/CMakeLists.txt index caa4aaa90..d3f74da8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 3.8 + VERSION 3.11 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/cmake/flags-gcc.cmake b/cmake/flags-gcc.cmake index 3339ad063..e1bf3650e 100644 --- a/cmake/flags-gcc.cmake +++ b/cmake/flags-gcc.cmake @@ -14,7 +14,7 @@ # # Define our flags -string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing") +string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition") string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing") string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3") string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3") @@ -32,4 +32,4 @@ foreach(LANG C;CXX) set(CMAKE_${LANG}_FLAGS_${CONFIG} "${CMAKE_${LANG}_FLAGS_${CONFIG}_INIT}" CACHE STRING "Flags used by the ${LANG} compiler during ${CONFIG} builds.") mark_as_advanced(CMAKE_${LANG}_FLAGS_${CONFIG}) endforeach() -endforeach() \ No newline at end of file +endforeach() diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..0ec15e546 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +86box (3.11.0-1) UNRELEASED; urgency=medium + + * Initial release. + + -- Jasmine Iwanek Sun, 18 Nov 2022 23:27:00 -0500 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..78a92bf8f --- /dev/null +++ b/debian/control @@ -0,0 +1,29 @@ +Source: 86box +Section: otherosfs +Priority: optional +Maintainer: Mariusz Kurek +Build-Depends: cmake (>= 3.21), + debhelper-compat (= 13), + libevdev-dev, + libfreetype-dev, + libopenal-dev, + libqt5opengl5-dev, + librtmidi-dev, + libsdl2-dev, + libslirp-dev, + ninja-build, + qttools5-dev +Standards-Version: 4.6.0 +Homepage: https://86box.net/ +#Vcs-Browser: https://salsa.debian.org/debian/86box +#Vcs-Git: https://salsa.debian.org/debian/86box.git +Rules-Requires-Root: no + +Package: 86box +Architecture: amd64 armhf arm64 i386 +Depends: ${shlibs:Depends}, + ${misc:Depends}, + sse2-support [i386] +Recommends: libpcap0.8-dev +Description: An emulator for classic IBM PC clones +#TODO: insert long description, indented with spaces diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..22817edc5 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,38 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: 86box +Source: https://86box.net/ + +Files: * +Copyright: + +License: GPL-2.0+ + +Files: debian/* +Copyright: 2022 Mariusz Kurek +License: GPL-2.0+ + +License: GPL-2.0+ + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". + +# Please also look if there are files or directories which have a +# different copyright/license attached and list them here. +# Please avoid picking licenses with terms that are more restrictive than the +# packaged work, as it may make Debian's contributions unacceptable upstream. +# +# If you need, there are some extra license texts available in two places: +# /usr/share/debhelper/dh_make/licenses/ +# /usr/share/common-licenses/ diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 000000000..b3080e419 --- /dev/null +++ b/debian/postinst @@ -0,0 +1,41 @@ +#!/bin/sh +# postinst script for 86box +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see https://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + echo You need ROM files in order to use 86Box. These can be obtained from https://github.com/86Box/roms + echo You can put the roms folder in, for example, /usr/share/86Box/roms or \~/.local/share/86Box/roms + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..f01d81dcd --- /dev/null +++ b/debian/rules @@ -0,0 +1,42 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + +ARCH=$(shell dpkg-architecture -qDEB_HOST_ARCH) + +ifeq ($(ARCH), $(filter $(ARCH), amd64 i386)) + NDR=off + ifeq ($(ARCH),amd64) + TOOLCHAIN=cmake/flags-gcc-x86_64.cmake + else + TOOLCHAIN=cmake/flags-gcc-i686.cmake + endif +else + NDR=on + ifeq ($(ARCH),armhf) + TOOLCHAIN=cmake/flags-gcc-armv7.cmake + else + TOOLCHAIN=cmake/flags-gcc-aarch64.cmake + endif +endif + +%: + dh $@ --buildsystem cmake+ninja + +override_dh_auto_configure: + dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR) -DSLIRP_EXTERNAL=on + +override_dh_auto_test: + +override_dh_auto_install: + dh_auto_install --buildsystem cmake+ninja + for i in 48x48 64x64 72x72 96x96 128x128 192x192 256x256 512x512 ; do \ + install -Dm644 src/unix/assets/$$i/net.86box.86Box.png -t debian/86box/usr/share/icons/hicolor/$$i/apps ; \ + done + mkdir debian/86box/usr/share/applications + sed 's/^Exec.*/Exec=86Box -P .local\/share\/86Box/' "src/unix/assets/net.86box.86Box.desktop" > "debian/86box/usr/share/applications/net.86box.86Box.desktop" + +override_dh_installdocs: + +override_dh_installman: diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..163aaf8d8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/watch b/debian/watch new file mode 100644 index 000000000..6f790c753 --- /dev/null +++ b/debian/watch @@ -0,0 +1,15 @@ +# Example watch control file for uscan +# Rename this file to "watch" and then you can run the "uscan" command +# to check for upstream updates and more. +# See uscan(1) for format + +# Compulsory line, this is a version 4 file +version=4 + +# PGP signature mangle, so foo.tar.gz has foo.tar.gz.sig +#opts="pgpsigurlmangle=s%$%.sig%" + +# GitHub hosted projects +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%-$1.tar.gz%" \ + https://github.com/86Box/86Box/tags \ + (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate diff --git a/src/86box.c b/src/86box.c index 2c29b69ea..235a1fd5d 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1,24 +1,24 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Main emulator module where most things are controlled. + * Main emulator module where most things are controlled. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2021 Laci bá' - * Copyright 2021 dob205 + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2021 Laci bá' + * Copyright 2021 dob205 */ #include #include @@ -205,15 +205,15 @@ char exe_path[2048]; /* path (dir) of executable */ char usr_path[1024]; /* path (dir) of user data */ char cfg_path[1024]; /* full path of config file */ FILE *stdlog = NULL; /* file to log output to */ -// int scrnsz_x = SCREEN_RES_X; /* current screen size, X */ -// int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ +// int scrnsz_x = SCREEN_RES_X; /* current screen size, X */ +// int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ int config_changed; /* config has changed */ int title_update; int framecountx = 0; int hard_reset_pending = 0; -// int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */ -// int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */ +// int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */ +// int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */ // int efscrnsz_y = SCREEN_RES_Y; static wchar_t mouse_msg[3][200]; @@ -473,7 +473,7 @@ usage: printf("-D or --debug - force debug output logging\n"); #endif #if 0 - printf("-E or --nographic - forces the old behavior\n"); + printf("-E or --nographic - forces the old behavior\n"); #endif printf("-F or --fullscreen - start in fullscreen mode\n"); printf("-G or --lang langid - start with specified language (e.g. en-US, or system)\n"); @@ -769,7 +769,7 @@ usage: for (i = 0; i < FDD_NUM; i++) { if (fn[i] != NULL) { - if (strlen(fn[i]) <= 511) + if (strlen(fn[i]) <= 511) strncpy(floppyfns[i], fn[i], 511); free(fn[i]); fn[i] = NULL; @@ -854,7 +854,7 @@ pc_init_modules(void) machine = -1; while (machine_get_internal_name_ex(c) != NULL) { if (machine_available(c)) { - ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2128, temp); + ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp); machine = c; config_save(); break; @@ -877,7 +877,7 @@ pc_init_modules(void) while (video_get_internal_name(c) != NULL) { gfxcard = -1; if (video_card_available(c)) { - ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2128, temp); + ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp); gfxcard = c; config_save(); break; @@ -892,11 +892,10 @@ pc_init_modules(void) } if (!video_card_available(gfxcard_2)) { - char temp[1024] = { 0 }; - char tempc[1024] = { 0 }; + char tempc[512] = { 0 }; device_get_name(video_card_getdevice(gfxcard_2), 0, tempc); - snprintf(temp, sizeof(temp), "Video card #2 \"%s\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.", tempc); - ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2128, temp); + swprintf(temp, sizeof(temp), (wchar_t *) "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.", tempc); + ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp); gfxcard_2 = 0; } @@ -1122,7 +1121,7 @@ pc_reset_hard_init(void) } void -update_mouse_msg() +update_mouse_msg(void) { wchar_t wcpufamily[2048], wcpu[2048], wmachine[2048], *wcp; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 18302d6fe..94a6f1821 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,18 +1,18 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, -# dob205 +# Authors: David Hrdlička, +# dob205 # -# Copyright 2020-2022 David Hrdlička. -# Copyright 2021 dob205. +# Copyright 2020-2022 David Hrdlička. +# Copyright 2021 dob205. # if(APPLE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) diff --git a/src/acpi.c b/src/acpi.c index 4923e3d9b..5f9db8d05 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -63,7 +63,7 @@ acpi_log(const char *fmt, ...) #endif static uint64_t -acpi_clock_get() +acpi_clock_get(void) { return tsc * cpu_to_acpi; } diff --git a/src/apm.c b/src/apm.c index d4e85d837..76fc24257 100644 --- a/src/apm.c +++ b/src/apm.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Advanced Power Management emulation. + * Advanced Power Management emulation. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2019 Miran Grca. + * Copyright 2019 Miran Grca. */ #include #include diff --git a/src/arch_detect.c b/src/arch_detect.c index 42ebde095..42a7d29bf 100644 --- a/src/arch_detect.c +++ b/src/arch_detect.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Configure-time architecture detection for the CMake build. + * Configure-time architecture detection for the CMake build. * * * - * Authors: David Hrdlička, + * Authors: David Hrdlička, * - * Copyright 2020-2021 David Hrdlička. + * Copyright 2020-2021 David Hrdlička. */ #if defined(__arm__) || defined(__TARGET_ARCH_ARM) diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt index 6ed0acb0c..c09a040bd 100644 --- a/src/cdrom/CMakeLists.txt +++ b/src/cdrom/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_mitsumi.c) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 1209f09ad..ae7278742 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1,16 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Generic CD-ROM drive core. + * Generic CD-ROM drive core. * - * Author: Miran Grca, * - * Copyright 2018-2021 Miran Grca. + * + * Authors: Miran Grca, + * + * Copyright 2018-2021 Miran Grca. */ #include #include diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 11a53aacc..2742d0e80 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -1,20 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * CD-ROM image support. + * CD-ROM image support. * - * Author: RichardG867, - * Miran Grca, - * bit, * - * Copyright 2015-2019 Richardg867. - * Copyright 2015-2019 Miran Grca. - * Copyright 2017-2019 bit. + * + * Authors: RichardG867, + * Miran Grca, + * bit, + * + * Copyright 2015-2019 Richardg867. + * Copyright 2015-2019 Miran Grca. + * Copyright 2017-2019 bit. */ #include #include diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 19968fe2b..d3f48578d 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -9,6 +9,8 @@ * CD-ROM image file handling module, translated to C from * cdrom_dosbox.cpp. * + * + * * Authors: Miran Grca, * Fred N. van Kempen, * The DOSBox Team, @@ -133,7 +135,7 @@ static track_file_t * bin_init(const char *filename, int *error) { track_file_t *tf = (track_file_t *) malloc(sizeof(track_file_t)); - struct stat stats; + struct stat stats; if (tf == NULL) { *error = 1; diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 9cac65b70..d4fc2b2a9 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -8,13 +8,18 @@ * * Virtual ISO CD-ROM image back-end. * + * + * * Authors: RichardG * * Copyright 2022 RichardG. */ -// clang-format off -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE +#ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE +#endif +#ifndef _LARGEFILE64_SOURCE +# define _LARGEFILE64_SOURCE +#endif #define __STDC_FORMAT_MACROS #include #include @@ -36,7 +41,6 @@ #include <86box/version.h> #include <86box/timer.h> #include <86box/nvr.h> -// clang-format on #ifndef S_ISDIR # define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR) @@ -85,9 +89,9 @@ enum { }; enum { - VISO_FORMAT_HSF = 0, /* High Sierra */ - VISO_FORMAT_ISO, /* ISO 9660 */ - VISO_FORMAT_ISO_LFN /* ISO 9660 with Joliet and Rock Ridge */ + VISO_FORMAT_ISO = 1, /* ISO 9660 (High Sierra if not set) */ + VISO_FORMAT_JOLIET = 2, /* Joliet extensions (Microsoft) */ + VISO_FORMAT_RR = 4 /* Rock Ridge extensions (*nix) */ }; typedef struct _viso_entry_ { @@ -111,7 +115,7 @@ typedef struct _viso_entry_ { typedef struct { uint64_t vol_size_offsets[2], pt_meta_offsets[2]; - int format; + int format, use_version_suffix : 1; size_t metadata_sectors, all_sectors, entry_map_size, sector_size, file_fifo_pos; uint8_t *metadata; @@ -296,7 +300,7 @@ static int viso_fill_fn_short(char *data, const viso_entry_t *entry, viso_entry_t **entries) { /* Get name and extension length. */ - const char *ext_pos = S_ISDIR(entry->stats.st_mode) ? NULL : strrchr(entry->basename, '.'); + const char *ext_pos = strrchr(entry->basename, '.'); int name_len, ext_len; if (ext_pos) { name_len = ext_pos - entry->basename; @@ -440,7 +444,7 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform) time_s->tm_mday = 1; } else if (time_s->tm_year > (longform ? 8099 : 255)) { time_s->tm_year = longform ? 8099 : 255; - time_s->tm_mon = 12; + time_s->tm_mon = 11; time_s->tm_mday = 31; time_s->tm_hour = 23; time_s->tm_min = time_s->tm_sec = 59; @@ -459,14 +463,14 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform) *p++ = time_s->tm_min; /* minute */ *p++ = time_s->tm_sec; /* second */ } - if (format >= VISO_FORMAT_ISO) + if (format & VISO_FORMAT_ISO) *p++ = tz_offset; /* timezone (ISO only) */ return p - data; } static int -viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type) +viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, viso_t *viso, int type) { uint8_t *p = data, *q, *r; @@ -478,11 +482,11 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type) if (entry->stats.st_mtime < 0) pclog("VISO: Warning: Windows returned st_mtime %lld on file [%s]\n", (long long) entry->stats.st_mtime, entry->path); #endif - p += viso_fill_time(p, entry->stats.st_mtime, format, 0); /* time */ - *p++ = S_ISDIR(entry->stats.st_mode) ? 0x02 : 0x00; /* flags */ + p += viso_fill_time(p, entry->stats.st_mtime, viso->format, 0); /* time */ + *p++ = S_ISDIR(entry->stats.st_mode) ? 0x02 : 0x00; /* flags */ - VISO_SKIP(p, 2 + (format <= VISO_FORMAT_HSF)); /* file unit size (reserved on HSF), interleave gap size (HSF/ISO) and skip factor (HSF only) */ - VISO_LBE_16(p, 1); /* volume sequence number */ + VISO_SKIP(p, 2 + !(viso->format & VISO_FORMAT_ISO)); /* file unit size (reserved on HSF), interleave gap size (HSF/ISO) and skip factor (HSF only) */ + VISO_LBE_16(p, 1); /* volume sequence number */ switch (type) { case VISO_DIR_CURRENT: @@ -492,7 +496,7 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type) *p++ = (type == VISO_DIR_PARENT) ? 1 : 0; /* magic value corresponding to . or .. */ /* Fill Rock Ridge Extension Record for the root directory's . entry. */ - if ((type == VISO_DIR_CURRENT_ROOT) && (format >= VISO_FORMAT_ISO_LFN)) { + if ((type == VISO_DIR_CURRENT_ROOT) && (viso->format & VISO_FORMAT_RR)) { *p++ = 'E'; *p++ = 'R'; *p++ = 8 + (sizeof(rr_eid) - 1) + (sizeof(rr_edesc) - 1); /* length */ @@ -518,8 +522,8 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type) *q = strlen(entry->name_short); memcpy(p, entry->name_short, *q); /* file ID */ p += *q; - if ((format >= VISO_FORMAT_ISO) && !S_ISDIR(entry->stats.st_mode)) { - *p++ = ';'; /* version suffix for files (ISO only?) */ + if (viso->use_version_suffix && !S_ISDIR(entry->stats.st_mode)) { + *p++ = ';'; /* version suffix for files (ISO only, except for Windows NT SETUPLDR.BIN El Torito hack) */ *p++ = '1'; *q += 2; } @@ -528,7 +532,7 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type) *p++ = 0; /* Fill Rock Ridge data. */ - if (format >= VISO_FORMAT_ISO_LFN) { + if (viso->format & VISO_FORMAT_RR) { *p++ = 'R'; /* RR = present Rock Ridge entries (only documented by RRIP revision 1.09!) */ *p++ = 'R'; *p++ = 5; /* length */ @@ -584,14 +588,14 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type) *p++ = times; /* flags */ #ifdef st_birthtime if (times & (1 << 0)) - p += viso_fill_time(p, entry->stats.st_birthtime, format, 0); /* creation */ + p += viso_fill_time(p, entry->stats.st_birthtime, viso->format, 0); /* creation */ #endif if (times & (1 << 1)) - p += viso_fill_time(p, entry->stats.st_mtime, format, 0); /* modify */ + p += viso_fill_time(p, entry->stats.st_mtime, viso->format, 0); /* modify */ if (times & (1 << 2)) - p += viso_fill_time(p, entry->stats.st_atime, format, 0); /* access */ + p += viso_fill_time(p, entry->stats.st_atime, viso->format, 0); /* access */ if (times & (1 << 3)) - p += viso_fill_time(p, entry->stats.st_ctime, format, 0); /* attributes */ + p += viso_fill_time(p, entry->stats.st_ctime, viso->format, 0); /* attributes */ *r += p - r; /* add to length */ } @@ -760,8 +764,9 @@ viso_init(const char *dirname, int *error) *error = 1; if (viso == NULL) goto end; - viso->sector_size = VISO_SECTOR_SIZE; - viso->format = VISO_FORMAT_ISO_LFN; + viso->sector_size = VISO_SECTOR_SIZE; + viso->format = VISO_FORMAT_ISO | VISO_FORMAT_JOLIET | VISO_FORMAT_RR; + viso->use_version_suffix = (viso->format & VISO_FORMAT_ISO); /* cleared later if required */ /* Prepare temporary data buffers. */ data = calloc(2, viso->sector_size); @@ -793,7 +798,6 @@ viso_init(const char *dirname, int *error) if (!dir) goto end; strcpy(dir->path, dirname); - strcpy(dir->name_short, "[root]"); if (stat(dirname, &dir->stats) != 0) { /* Use a blank structure if stat failed. */ memset(&dir->stats, 0x00, sizeof(struct stat)); @@ -801,7 +805,7 @@ viso_init(const char *dirname, int *error) if (!S_ISDIR(dir->stats.st_mode)) /* root is not a directory */ goto end; dir->parent = dir; /* for the root's path table and .. entries */ - cdrom_image_viso_log("[%08X] %s => %s\n", dir, dir->path, dir->name_short); + cdrom_image_viso_log("[%08X] %s => [root]\n", dir, dir->path); /* Traverse directories, starting with the root. */ viso_entry_t **dir_entries = NULL; @@ -809,16 +813,16 @@ viso_init(const char *dirname, int *error) while (dir) { /* Open directory for listing. */ DIR *dirp = opendir(dir->path); - if (!dirp) - goto next_dir; /* Iterate through this directory's children to determine the entry array size. */ size_t children_count = 3; /* include terminator, . and .. */ - while ((readdir_entry = readdir(dirp))) { - /* Ignore . and .. pseudo-directories. */ - if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || ((readdir_entry->d_name[1] == '.') && (readdir_entry->d_name[2] == '\0')))) - continue; - children_count++; + if (dirp) { /* create empty directory if opendir failed */ + while ((readdir_entry = readdir(dirp))) { + /* Ignore . and .. pseudo-directories. */ + if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || (*((uint16_t *) &readdir_entry->d_name[1]) == '.'))) + continue; + children_count++; + } } /* Grow array if needed. */ @@ -855,77 +859,89 @@ viso_init(const char *dirname, int *error) } /* Iterate through this directory's children again, making the entries. */ - rewinddir(dirp); - while ((readdir_entry = readdir(dirp))) { - /* Ignore . and .. pseudo-directories. */ - if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || ((readdir_entry->d_name[1] == '.') && (readdir_entry->d_name[2] == '\0')))) - continue; + if (dirp) { + rewinddir(dirp); + while ((readdir_entry = readdir(dirp))) { + /* Ignore . and .. pseudo-directories. */ + if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || (*((uint16_t *) &readdir_entry->d_name[1]) == '.'))) + continue; - /* Add and fill entry. */ - entry = dir_entries[children_count++] = (viso_entry_t *) calloc(1, sizeof(viso_entry_t) + dir_path_len + strlen(readdir_entry->d_name) + 2); - if (!entry) - break; - entry->parent = dir; - strcpy(entry->path, dir->path); - path_slash(&entry->path[dir_path_len]); - entry->basename = &entry->path[dir_path_len + 1]; - strcpy(entry->basename, readdir_entry->d_name); + /* Add and fill entry. */ + entry = dir_entries[children_count++] = (viso_entry_t *) calloc(1, sizeof(viso_entry_t) + dir_path_len + strlen(readdir_entry->d_name) + 2); + if (!entry) + break; + entry->parent = dir; + strcpy(entry->path, dir->path); + path_slash(&entry->path[dir_path_len]); + entry->basename = &entry->path[dir_path_len + 1]; + strcpy(entry->basename, readdir_entry->d_name); - /* Stat this child. */ - if (stat(entry->path, &entry->stats) != 0) { - /* Use a blank structure if stat failed. */ - memset(&entry->stats, 0x00, sizeof(struct stat)); - } - - /* Handle file size and El Torito boot code. */ - if (!S_ISDIR(entry->stats.st_mode)) { - /* Clamp to 4 GB - 1 byte. */ - if (entry->stats.st_size > ((uint32_t) -1)) - entry->stats.st_size = (uint32_t) -1; - - /* Increase entry map size. */ - viso->entry_map_size += entry->stats.st_size / viso->sector_size; - if (entry->stats.st_size % viso->sector_size) - viso->entry_map_size++; /* round up to the next sector */ - - /* Detect El Torito boot code file and set it accordingly. */ - if (dir == eltorito_dir) { - if (!stricmp(readdir_entry->d_name, "Boot-NoEmul.img")) { - eltorito_type = 0x00; -have_eltorito_entry: - if (eltorito_entry) - eltorito_others_present = 1; /* flag that the boot code directory contains other files */ - eltorito_entry = entry; - } else if (!stricmp(readdir_entry->d_name, "Boot-1.2M.img")) { - eltorito_type = 0x01; - goto have_eltorito_entry; - } else if (!stricmp(readdir_entry->d_name, "Boot-1.44M.img")) { - eltorito_type = 0x02; - goto have_eltorito_entry; - } else if (!stricmp(readdir_entry->d_name, "Boot-2.88M.img")) { - eltorito_type = 0x03; - goto have_eltorito_entry; - } else if (!stricmp(readdir_entry->d_name, "Boot-HardDisk.img")) { - eltorito_type = 0x04; - goto have_eltorito_entry; - } else { - eltorito_others_present = 1; /* flag that the boot code directory contains other files */ - } + /* Stat this child. */ + if (stat(entry->path, &entry->stats) != 0) { + /* Use a blank structure if stat failed. */ + memset(&entry->stats, 0x00, sizeof(struct stat)); } - } else if ((dir == viso->root_dir) && !stricmp(readdir_entry->d_name, "[BOOT]")) { - /* Set this as the directory containing El Torito boot code. */ - eltorito_dir = entry; - eltorito_others_present = 0; - } - /* Set short filename. */ - if (viso_fill_fn_short(entry->name_short, entry, dir_entries)) { - free(entry); - children_count--; - continue; - } + /* Handle file size and El Torito boot code. */ + if (!S_ISDIR(entry->stats.st_mode)) { + /* Clamp file size to 4 GB - 1 byte. */ + if (entry->stats.st_size > ((uint32_t) -1)) + entry->stats.st_size = (uint32_t) -1; - cdrom_image_viso_log("[%08X] %s => [%-12s] %s\n", entry, dir->path, entry->name_short, entry->basename); + /* Increase entry map size. */ + viso->entry_map_size += entry->stats.st_size / viso->sector_size; + if (entry->stats.st_size % viso->sector_size) + viso->entry_map_size++; /* round up to the next sector */ + + /* Detect El Torito boot code file and set it accordingly. */ + if (dir == eltorito_dir) { + if (!stricmp(readdir_entry->d_name, "Boot-NoEmul.img")) { + eltorito_type = 0x00; +have_eltorito_entry: + if (eltorito_entry) + eltorito_others_present = 1; /* flag that the boot code directory contains other files */ + eltorito_entry = entry; + } else if (!stricmp(readdir_entry->d_name, "Boot-1.2M.img")) { + eltorito_type = 0x01; + goto have_eltorito_entry; + } else if (!stricmp(readdir_entry->d_name, "Boot-1.44M.img")) { + eltorito_type = 0x02; + goto have_eltorito_entry; + } else if (!stricmp(readdir_entry->d_name, "Boot-2.88M.img")) { + eltorito_type = 0x03; + goto have_eltorito_entry; + } else if (!stricmp(readdir_entry->d_name, "Boot-HardDisk.img")) { + eltorito_type = 0x04; + goto have_eltorito_entry; + } else { + eltorito_others_present = 1; /* flag that the boot code directory contains other files */ + } + } else { + /* Disable version suffixes if this structure appears to contain the Windows NT + El Torito boot code, which is known not to tolerate suffixed file names. */ + if (eltorito_dir && /* El Torito directory present? */ + (eltorito_type == 0x00) && /* El Torito directory not checked yet, or confirmed to contain non-emulation boot code? */ + (dir->parent == viso->root_dir) && /* one subdirectory deep? (I386 for instance) */ + !stricmp(readdir_entry->d_name, "SETUPLDR.BIN")) /* SETUPLDR.BIN present? */ + viso->use_version_suffix = 0; + } + } else if ((dir == viso->root_dir) && !stricmp(readdir_entry->d_name, "[BOOT]")) { + /* Set this as the directory containing El Torito boot code. */ + eltorito_dir = entry; + eltorito_others_present = 0; + } + + /* Set short filename. */ + if (viso_fill_fn_short(entry->name_short, entry, dir_entries)) { + free(entry); + children_count--; + continue; + } + + cdrom_image_viso_log("[%08X] %s => [%-12s] %s\n", entry, dir->path, entry->name_short, entry->basename); + } + } else { + cdrom_image_viso_log("VISO: Failed to enumerate [%s], will be empty\n", dir->path); } /* Add terminator. */ @@ -947,6 +963,8 @@ have_eltorito_entry: next_dir: /* Move on to the next directory. */ + if (dirp) + closedir(dirp); dir = dir->next_dir; } if (dir_entries) @@ -960,21 +978,26 @@ next_dir: the timezone offset for descriptors and file times to use. */ tzset(); time_t now = time(NULL); - tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4); + if (viso->format & VISO_FORMAT_ISO) /* timezones are ISO only */ + tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4); /* Get root directory basename for the volume ID. */ char *basename = path_get_filename(viso->root_dir->path); if (!basename || (basename[0] == '\0')) basename = EMU_NAME; + /* Determine whether or not we're working with 2 volume descriptors + (as well as 2 directory trees and 4 path tables) for Joliet. */ + int max_vd = (viso->format & VISO_FORMAT_JOLIET) ? 1 : 0; + /* Write volume descriptors. */ - for (int i = 0; i <= (viso->format >= VISO_FORMAT_ISO_LFN); i++) { + for (int i = 0; i <= max_vd; i++) { /* Fill volume descriptor. */ p = data; - if (viso->format <= VISO_FORMAT_HSF) - VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */ - *p++ = 1 + i; /* type */ - memcpy(p, (viso->format <= VISO_FORMAT_HSF) ? "CDROM" : "CD001", 5); /* standard ID */ + if (!(viso->format & VISO_FORMAT_ISO)) + VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */ + *p++ = 1 + i; /* type */ + memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */ p += 5; *p++ = 1; /* version */ *p++ = 0; /* unused */ @@ -1013,11 +1036,12 @@ next_dir: /* Path table metadata is filled in later. */ viso->pt_meta_offsets[i] = ftello64(viso->tf.file) + (p - data); - VISO_SKIP(p, 24 + (16 * (viso->format <= VISO_FORMAT_HSF))); /* PT size, LE PT offset, optional LE PT offset (three on HSF), BE PT offset, optional BE PT offset (three on HSF) */ + VISO_SKIP(p, 24 + (16 * !(viso->format & VISO_FORMAT_ISO))); /* PT size, LE PT offset, optional LE PT offset (three on HSF), BE PT offset, optional BE PT offset (three on HSF) */ viso->root_dir->dr_offsets[i] = ftello64(viso->tf.file) + (p - data); - p += viso_fill_dir_record(p, viso->root_dir, viso->format, VISO_DIR_CURRENT); /* root directory */ + p += viso_fill_dir_record(p, viso->root_dir, viso, VISO_DIR_CURRENT); /* root directory */ + int copyright_abstract_len = (viso->format & VISO_FORMAT_ISO) ? 37 : 32; if (i) { viso_write_wstring((uint16_t *) p, L"", 64, VISO_CHARSET_D); /* volume set ID */ p += 128; @@ -1027,11 +1051,11 @@ next_dir: p += 128; viso_write_wstring((uint16_t *) p, EMU_NAME_W L" " EMU_VERSION_W L" VIRTUAL ISO", 64, VISO_CHARSET_A); /* application ID */ p += 128; - viso_write_wstring((uint16_t *) p, L"", (viso->format <= VISO_FORMAT_HSF) ? 16 : 18, VISO_CHARSET_D); /* copyright file ID */ - p += (viso->format <= VISO_FORMAT_HSF) ? 32 : 37; - viso_write_wstring((uint16_t *) p, L"", (viso->format <= VISO_FORMAT_HSF) ? 16 : 18, VISO_CHARSET_D); /* abstract file ID */ - p += (viso->format <= VISO_FORMAT_HSF) ? 32 : 37; - if (viso->format >= VISO_FORMAT_ISO) { + viso_write_wstring((uint16_t *) p, L"", copyright_abstract_len >> 1, VISO_CHARSET_D); /* copyright file ID */ + p += copyright_abstract_len; + viso_write_wstring((uint16_t *) p, L"", copyright_abstract_len >> 1, VISO_CHARSET_D); /* abstract file ID */ + p += copyright_abstract_len; + if (viso->format & VISO_FORMAT_ISO) { viso_write_wstring((uint16_t *) p, L"", 18, VISO_CHARSET_D); /* bibliography file ID (ISO only) */ p += 37; } @@ -1044,11 +1068,11 @@ next_dir: p += 128; viso_write_string(p, EMU_NAME " " EMU_VERSION " VIRTUAL ISO", 128, VISO_CHARSET_A); /* application ID */ p += 128; - viso_write_string(p, "", (viso->format <= VISO_FORMAT_HSF) ? 32 : 37, VISO_CHARSET_D); /* copyright file ID */ - p += (viso->format <= VISO_FORMAT_HSF) ? 32 : 37; - viso_write_string(p, "", (viso->format <= VISO_FORMAT_HSF) ? 32 : 37, VISO_CHARSET_D); /* abstract file ID */ - p += (viso->format <= VISO_FORMAT_HSF) ? 32 : 37; - if (viso->format >= VISO_FORMAT_ISO) { + viso_write_string(p, "", copyright_abstract_len, VISO_CHARSET_D); /* copyright file ID */ + p += copyright_abstract_len; + viso_write_string(p, "", copyright_abstract_len, VISO_CHARSET_D); /* abstract file ID */ + p += copyright_abstract_len; + if (viso->format & VISO_FORMAT_ISO) { viso_write_string(p, "", 37, VISO_CHARSET_D); /* bibliography file ID (ISO only) */ p += 37; } @@ -1074,10 +1098,10 @@ next_dir: cdrom_image_viso_log("VISO: Writing El Torito boot descriptor for entry [%08X]\n", eltorito_entry); p = data; - if (viso->format <= VISO_FORMAT_HSF) - VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */ - *p++ = 0; /* type */ - memcpy(p, (viso->format <= VISO_FORMAT_HSF) ? "CDROM" : "CD001", 5); /* standard ID */ + if (!(viso->format & VISO_FORMAT_ISO)) + VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */ + *p++ = 0; /* type */ + memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */ p += 5; *p++ = 1; /* version */ @@ -1098,10 +1122,10 @@ next_dir: /* Fill terminator. */ p = data; - if (viso->format <= VISO_FORMAT_HSF) - VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */ - *p++ = 0xff; /* type */ - memcpy(p, (viso->format <= VISO_FORMAT_HSF) ? "CDROM" : "CD001", 5); /* standard ID */ + if (!(viso->format & VISO_FORMAT_ISO)) + VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */ + *p++ = 0xff; /* type */ + memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */ p += 5; *p++ = 1; /* version */ @@ -1177,7 +1201,7 @@ next_dir: } /* Write each path table. */ - for (int i = 0; i <= ((viso->format >= VISO_FORMAT_ISO_LFN) ? 3 : 1); i++) { + for (int i = 0; i <= ((max_vd << 1) | 1); i++) { cdrom_image_viso_log("VISO: Generating path table #%d:\n", i); /* Save this path table's start offset. */ @@ -1207,7 +1231,7 @@ next_dir: /* Fill path table entry. */ p = data; - if (viso->format <= VISO_FORMAT_HSF) { + if (!(viso->format & VISO_FORMAT_ISO)) { *((uint32_t *) p) = 0; /* extent location (filled in later) */ p += 4; *p++ = 0; /* extended attribute length */ @@ -1223,16 +1247,17 @@ next_dir: *((uint16_t *) p) = (i & 1) ? cpu_to_be16(dir->parent->pt_idx) : cpu_to_le16(dir->parent->pt_idx); /* parent directory number */ p += 2; - if (dir == viso->root_dir) { /* directory ID and length */ - data[5 * (viso->format <= VISO_FORMAT_HSF)] = 1; - *p = 0x00; - } else if (i & 2) { - data[5 * (viso->format <= VISO_FORMAT_HSF)] = viso_fill_fn_joliet(p, dir, 255); - } else { - data[5 * (viso->format <= VISO_FORMAT_HSF)] = strlen(dir->name_short); - memcpy(p, dir->name_short, data[5 * (viso->format <= VISO_FORMAT_HSF)]); + pt_temp = 5 * !(viso->format & VISO_FORMAT_ISO); /* directory ID length at offset 0 for ISO, 5 for HSF */ + if (dir == viso->root_dir) { /* directory ID length then ID for root... */ + data[pt_temp] = 1; + *p = 0x00; + } else if (i & 2) { /* ...or Joliet... */ + data[pt_temp] = viso_fill_fn_joliet(p, dir, 255); + } else { /* ...or short name */ + data[pt_temp] = strlen(dir->name_short); + memcpy(p, dir->name_short, data[pt_temp]); } - p += data[5 * (viso->format <= VISO_FORMAT_HSF)]; + p += data[pt_temp]; if ((p - data) & 1) /* padding for odd directory ID lengths */ *p++ = 0x00; @@ -1265,7 +1290,7 @@ next_dir: /* Write directory records for each type. */ int dir_type = VISO_DIR_CURRENT_ROOT; - for (int i = 0; i <= (viso->format >= VISO_FORMAT_ISO_LFN); i++) { + for (int i = 0; i <= max_vd; i++) { cdrom_image_viso_log("VISO: Generating directory record set #%d:\n", i); /* Go through directories. */ @@ -1298,7 +1323,7 @@ next_dir: viso_pwrite(data, dir->pt_offsets[i << 1], 4, 1, viso->tf.file); /* little endian */ viso_pwrite(data + 4, dir->pt_offsets[(i << 1) | 1], 4, 1, viso->tf.file); /* big endian */ - if (i == (viso->format >= VISO_FORMAT_ISO_LFN)) /* overwrite pt_offsets in the union if we no longer need them */ + if (i == max_vd) /* overwrite pt_offsets in the union if we no longer need them */ dir->file = NULL; /* Go through entries in this directory. */ @@ -1313,7 +1338,7 @@ next_dir: ((dir_type == VISO_DIR_PARENT) ? ".." : ((dir_type < VISO_DIR_PARENT) ? "." : (i ? entry->basename : entry->name_short)))); /* Fill directory record. */ - viso_fill_dir_record(data, entry, viso->format, dir_type); + viso_fill_dir_record(data, entry, viso, dir_type); /* Entries cannot cross sector boundaries, so pad to the next sector if needed. */ write = viso->sector_size - (ftello64(viso->tf.file) % viso->sector_size); @@ -1452,7 +1477,7 @@ next_entry: } else { p = data; VISO_LBE_32(p, viso->all_sectors * base_factor); - for (int i = 0; i <= (viso->format >= VISO_FORMAT_ISO_LFN); i++) + for (int i = 0; i <= max_vd; i++) viso_pwrite(data, entry->dr_offsets[i] + 2, 8, 1, viso->tf.file); } diff --git a/src/cdrom/cdrom_mitsumi.c b/src/cdrom/cdrom_mitsumi.c index 3ade6586c..a6ad860b3 100644 --- a/src/cdrom/cdrom_mitsumi.c +++ b/src/cdrom/cdrom_mitsumi.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Mitsumi CD-ROM emulation for the ISA bus. + * Mitsumi CD-ROM emulation for the ISA bus. * * * - * Author: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2022 Miran Grca. + * Copyright 2022 Miran Grca. */ #include #include @@ -183,7 +183,7 @@ mitsumi_cdrom_read_sector(mcd_t *dev, int first) return 0; } cdrom_stop(cdrom); - ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, &dev->readcount); + ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, (int *) &dev->readcount); if (!ret) return 0; if (dev->mode & 0x40) { diff --git a/src/chipset/82c100.c b/src/chipset/82c100.c index 7769ab66b..516768742 100644 --- a/src/chipset/82c100.c +++ b/src/chipset/82c100.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Chips&Technology's 82C100 chipset. + * Implementation of Chips&Technology's 82C100 chipset. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2021 Miran Grca. + * Copyright 2021 Miran Grca. */ #include #include diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 517630ae4..47b9b30ce 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1489.c ali1531.c ali1541.c ali1543.c diff --git a/src/chipset/acc2168.c b/src/chipset/acc2168.c index 60cca9327..7332a28a3 100644 --- a/src/chipset/acc2168.c +++ b/src/chipset/acc2168.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ACC 2046/2168 chipset + * Implementation of the ACC 2046/2168 chipset * * * - * Authors: Sarah Walker, + * Authors: Sarah Walker, * Tiseno100 * - * Copyright 2019 Sarah Walker. - * Copyright 2021 Tiseno100. + * Copyright 2019 Sarah Walker. + * Copyright 2021 Tiseno100. */ #include #include diff --git a/src/chipset/ali1429.c b/src/chipset/ali1429.c index 68ffd9fe0..699769fa2 100644 --- a/src/chipset/ali1429.c +++ b/src/chipset/ali1429.c @@ -1,21 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ALi M1429 chipset. + * Implementation of the ALi M1429 chipset. * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. * - * Authors: Tiseno100, - * Miran Grca, * - * Copyright 2020,2021 Tiseno100. - * Copyright 2021,2021 Miran Grca. + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2020,2021 Tiseno100. + * Copyright 2021,2021 Miran Grca. */ /* @@ -72,7 +74,6 @@ 1 1 0: CLK2IN/12 */ - #include #include #include @@ -323,8 +324,8 @@ ali1429_init(const device_t *info) GREEN = info->local; /* M1429 Ports: - 22h Index Port - 23h Data Port + 22h Index Port + 23h Data Port */ io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev); diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index e42033a7d..8a0cfd89a 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ALi M1489 chipset. + * Implementation of the ALi M1489 chipset. * * * - * Authors: Tiseno100, - * Miran Grca, + * Authors: Tiseno100, + * Miran Grca, * - * Copyright 2020,2021 Tiseno100. - * Copyright 2020,2021 Miran Grca. + * Copyright 2020,2021 Tiseno100. + * Copyright 2020,2021 Miran Grca. */ #include #include diff --git a/src/chipset/ali1531.c b/src/chipset/ali1531.c index 438d351e5..b92421e31 100644 --- a/src/chipset/ali1531.c +++ b/src/chipset/ali1531.c @@ -1,19 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ALi M1531B CPU-to-PCI Bridge. + * Implementation of the ALi M1531B CPU-to-PCI Bridge. * * * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. + * Authors: Tiseno100, * + * Copyright 2021 Tiseno100. */ #include #include diff --git a/src/chipset/ali1541.c b/src/chipset/ali1541.c index 7cf6ca166..37dd7c809 100644 --- a/src/chipset/ali1541.c +++ b/src/chipset/ali1541.c @@ -1,16 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ALi M1541/2 CPU-to-PCI Bridge. + * Implementation of the ALi M1541/2 CPU-to-PCI Bridge. * - * Authors: Miran Grca, * - * Copyright 2021 Miran Grca. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. */ #include #include diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 70ba182e1..e6bfbf878 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -1,19 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ALi M1543 Desktop South Bridge. + * Implementation of the ALi M1543 Desktop South Bridge. * * * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. + * Authors: Tiseno100, * + * Copyright 2021 Tiseno100. */ #include #include diff --git a/src/chipset/ali1621.c b/src/chipset/ali1621.c index 3c5ab8cc2..7db437b24 100644 --- a/src/chipset/ali1621.c +++ b/src/chipset/ali1621.c @@ -1,16 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ALi M1621/2 CPU-to-PCI Bridge. + * Implementation of the ALi M1621/2 CPU-to-PCI Bridge. * - * Authors: Miran Grca, * - * Copyright 2021 Miran Grca. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. */ #include #include @@ -57,28 +59,28 @@ ali1621_log(const char *fmt, ...) /* Table translated to a more sensible format: Read cycles: - SMREN SMM Mode Code Data - 0 X X PCI PCI - 1 0 Close PCI PCI - 1 0 Lock PCI PCI - 1 0 Protect PCI PCI - 1 0 Open DRAM DRAM - 1 1 Open DRAM DRAM - 1 1 Protect DRAM DRAM - 1 1 Close DRAM PCI - 1 1 Lock DRAM PCI + SMREN SMM Mode Code Data + 0 X X PCI PCI + 1 0 Close PCI PCI + 1 0 Lock PCI PCI + 1 0 Protect PCI PCI + 1 0 Open DRAM DRAM + 1 1 Open DRAM DRAM + 1 1 Protect DRAM DRAM + 1 1 Close DRAM PCI + 1 1 Lock DRAM PCI Write cycles: - SMWEN SMM Mode Data - 0 X X PCI - 1 0 Close PCI - 1 0 Lock PCI - 1 0 Protect PCI - 1 0 Open DRAM - 1 1 Open DRAM - 1 1 Protect DRAM - 1 1 Close PCI - 1 1 Lock PCI + SMWEN SMM Mode Data + 0 X X PCI + 1 0 Close PCI + 1 0 Lock PCI + 1 0 Protect PCI + 1 0 Open DRAM + 1 1 Open DRAM + 1 1 Protect DRAM + 1 1 Close PCI + 1 1 Lock PCI Explanation of the modes based above: If SM*EN = 0, SMRAM is entirely disabled, otherwise: diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index 8f1b38627..700fe1405 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ALi M6117 SoC. + * Implementation of the ALi M6117 SoC. * * * - * Authors: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include diff --git a/src/chipset/contaq_82c59x.c b/src/chipset/contaq_82c59x.c index b724cbf4b..951a86b0a 100644 --- a/src/chipset/contaq_82c59x.c +++ b/src/chipset/contaq_82c59x.c @@ -1,18 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Contaq/Cypress 82C596(A) and 597 chipsets. + * Implementation of the Contaq/Cypress 82C596(A) and 597 chipsets. * - * Authors: Miran Grca, * - * Copyright 2021 Miran Grca. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. */ - #include #include #include diff --git a/src/chipset/cs4031.c b/src/chipset/cs4031.c index 9ae80578a..a2cef50b9 100644 --- a/src/chipset/cs4031.c +++ b/src/chipset/cs4031.c @@ -1,21 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Chips & Technologies CS4031 chipset. + * Implementation of the Chips & Technologies CS4031 chipset. * * * - * Authors: Tiseno100 - * - * Copyright 2021 Tiseno100 + * Authors: Tiseno100 * + * Copyright 2021 Tiseno100 */ - #include #include #include diff --git a/src/chipset/cs8230.c b/src/chipset/cs8230.c index 0917a3c88..49e7d71b6 100644 --- a/src/chipset/cs8230.c +++ b/src/chipset/cs8230.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of C&T CS8230 ("386/AT") chipset. + * Emulation of C&T CS8230 ("386/AT") chipset. * * * - * Authors: Sarah Walker, + * Authors: Sarah Walker, * - * Copyright 2020 Sarah Walker. + * Copyright 2020 Sarah Walker. */ #include #include diff --git a/src/chipset/et6000.c b/src/chipset/et6000.c index ab92d6fe6..eb42ac7cb 100644 --- a/src/chipset/et6000.c +++ b/src/chipset/et6000.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ETEQ Cheetah ET6000 chipset. + * Implementation of the ETEQ Cheetah ET6000 chipset. * - * Authors: Tiseno100 * - * Copyright 2021 Tiseno100 * + * Authors: Tiseno100 + * + * Copyright 2021 Tiseno100 */ - #include #include #include diff --git a/src/chipset/gc100.c b/src/chipset/gc100.c index 9ff577a1e..2aba21350 100644 --- a/src/chipset/gc100.c +++ b/src/chipset/gc100.c @@ -1,19 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the G2 GC100/GC100A chipset. - * NOTE: As documentation is currently available only for the - * CG100 chipset, the GC100A chipset has been reverese-engineered. - * Thus, its behavior may not be fully accurate. + * Implementation of the G2 GC100/GC100A chipset. * - * Authors: EngiNerd, + * NOTE: As documentation is currently available only for the + * GC100 chipset, the GC100A chipset has been reverese-engineered. + * Thus, its behavior may not be fully accurate. * - * Copyright 2020-2021 EngiNerd. + * + * + * Authors: EngiNerd, + * + * Copyright 2020-2021 EngiNerd. */ #include #include diff --git a/src/chipset/headland.c b/src/chipset/headland.c index 9aa6b3fac..c1881bede 100644 --- a/src/chipset/headland.c +++ b/src/chipset/headland.c @@ -1,24 +1,24 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the HEADLAND AT286 chipset. + * Implementation of the HEADLAND AT286 chipset. * * * - * Authors: Sarah Walker, - * Fred N. van Kempen, - * Original by GreatPsycho for PCem. - * Miran Grca, + * Authors: Sarah Walker, + * Fred N. van Kempen, + * Original by GreatPsycho for PCem. + * Miran Grca, * - * Copyright 2010-2019 Sarah Walker. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2017-2019 Miran Grca. - * Copyright 2017-2019 GreatPsycho. + * Copyright 2010-2019 Sarah Walker. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2019 Miran Grca. + * Copyright 2017-2019 GreatPsycho. */ #include #include @@ -255,7 +255,7 @@ memmap_state_update(headland_t *dev) mem_mapping_set_exec(&dev->high_mapping, ram + 0x100000); } } else { - /* 1 MB - 1 MB + 384k: RAM pointing to A0000-FFFFF + /* 1 MB - 1 MB + 384k: RAM pointing to A0000-FFFFF 1 MB + 384k: Any ram pointing 1 MB onwards. */ /* First, do the addresses above 1 MB. */ mem_mapping_set_addr(&dev->mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10); diff --git a/src/chipset/ims8848.c b/src/chipset/ims8848.c index c4273b4fe..0cdc833b5 100644 --- a/src/chipset/ims8848.c +++ b/src/chipset/ims8848.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the IMS 8848/8849 chipset. + * Implementation of the IMS 8848/8849 chipset. * * * - * Authors: Miran Grca, - * Tiseno100, + * Authors: Miran Grca, + * Tiseno100, * - * Copyright 2021 Miran Grca. - * Copyright 2021 Tiseno100. + * Copyright 2021 Miran Grca. + * Copyright 2021 Tiseno100. */ #include #include diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index e81782c1f..98c2d0386 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -1,17 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of Intel 82420EX chipset that acts as both the - * northbridge and the southbridge. + * This file is part of the 86Box distribution. + * + * Emulation of Intel 82420EX chipset that acts as both the + * northbridge and the southbridge. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020 Miran Grca. */ #include #include diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 7857f7f06..8f74c79d9 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Intel PCISet chips from 420TX to 440GX. + * Implementation of the Intel PCISet chips from 420TX to 440GX. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2019,2020 Miran Grca. + * Copyright 2019-2020 Miran Grca. */ #include #include diff --git a/src/chipset/intel_82335.c b/src/chipset/intel_82335.c index 20ae0981f..e945f35d1 100644 --- a/src/chipset/intel_82335.c +++ b/src/chipset/intel_82335.c @@ -1,17 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Intel 82335(KU82335) chipset. + * Implementation of the Intel 82335(KU82335) chipset. * - * Copyright 2021 Tiseno100 * + * + * Authors: Tiseno100 + * + * Copyright 2021 Tiseno100. */ - #include #include #include diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index 3c81ec11a..ac3746492 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -1,16 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Intel 450KX Mars Chipset. + * Implementation of the Intel 450KX Mars Chipset. * - * Authors: Tiseno100, * - * Copyright 2021 Tiseno100. + * + * Authors: Tiseno100 + * + * Copyright 2021 Tiseno100. */ /* @@ -19,7 +21,6 @@ Due to 86Box limitations we can't manage them seperately thus it is dev branch t i450GX is way more popular of an option but needs more stuff. */ - #include #include #include diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 7347be38e..180940e26 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of the Intel PIIX, PIIX3, PIIX4, PIIX4E, and SMSC - * SLC90E66 (Victory66) Xcelerators. + * Emulation of the Intel PIIX, PIIX3, PIIX4, PIIX4E, and SMSC + * SLC90E66 (Victory66) Xcelerators. * - * PRD format : - * word 0 - base address - * word 1 - bits 1-15 = byte count, bit 31 = end of transfer + * PRD format : + * word 0 - base address + * word 1 - bits 1-15 = byte count, bit 31 = end of transfer * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -1023,9 +1023,9 @@ piix_write(int func, int addr, uint8_t val, void *priv) fregs[0x07] &= 0xf7; break; #if 0 - case 0x3c: - fregs[0x3c] = val; - break; + case 0x3c: + fregs[0x3c] = val; + break; #endif case 0x40: fregs[0x40] = (val & 0xc0) | 1; @@ -1657,9 +1657,9 @@ static void /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ /* Bit 4: External CPU clock (Switch 8). */ /* Bit 3: External CPU clock (Switch 7). */ - /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ - /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ - /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ /* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */ /* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */ /* Bit 0: 0 = 1.5x multiplier, 1 = 2x multiplier (Switch 6). */ diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index d7c3ea073..d94cac04a 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of Intel System I/O PCI chip. + * Emulation of Intel System I/O PCI chip. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2018 Miran Grca. */ #include #include diff --git a/src/chipset/neat.c b/src/chipset/neat.c index 87c219f1f..83f3eb96a 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of C&T CS8121 ("NEAT") 82C206/211/212/215 chipset. + * Emulation of C&T CS8121 ("NEAT") 82C206/211/212/215 chipset. * - * Note: The datasheet mentions that the chipset supports up to 8MB - * of DRAM. This is intepreted as 'being able to refresh up to - * 8MB of DRAM chips', because it works fine with bus-based - * memory expansion. + * Note: The datasheet mentions that the chipset supports up to 8MB + * of DRAM. This is intepreted as 'being able to refresh up to + * 8MB of DRAM chips', because it works fine with bus-based + * memory expansion. * * * - * Author: Fred N. van Kempen, + * Authors: Fred N. van Kempen, * - * Copyright 2018 Fred N. van Kempen. + * Copyright 2018 Fred N. van Kempen. */ #include #include diff --git a/src/chipset/olivetti_eva.c b/src/chipset/olivetti_eva.c index 07b7eab6f..ce9ba9a1f 100644 --- a/src/chipset/olivetti_eva.c +++ b/src/chipset/olivetti_eva.c @@ -1,21 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. + * + * Implementation of the Olivetti EVA (98/86) Gate Array. + * + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. * - * Implementation of the Olivetti EVA (98/86) Gate Array. * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. * * Authors: EngiNerd * - * Copyright 2020-2021 EngiNerd + * Copyright 2020-2021 EngiNerd */ - #include #include #include diff --git a/src/chipset/opti283.c b/src/chipset/opti283.c index 7053e2f2f..b3b51d8fa 100644 --- a/src/chipset/opti283.c +++ b/src/chipset/opti283.c @@ -1,20 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C283 chipset. + * Implementation of the OPTi 82C283 chipset. * - * Authors: Tiseno100, - * Miran Grca, * - * Copyright 2021 Tiseno100. - * Copyright 2021 Miran Grca. + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2021 Tiseno100. + * Copyright 2021 Miran Grca. */ - #include #include #include diff --git a/src/chipset/opti291.c b/src/chipset/opti291.c index 0aafc538d..b15b71260 100644 --- a/src/chipset/opti291.c +++ b/src/chipset/opti291.c @@ -1,17 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C291 chipset. - - * Authors: plant/nerd73, Tiseno100 + * Implementation of the OPTi 82C291 chipset. * - * Copyright 2020 plant/nerd73. - * Copyright 2021 Tiseno100. + * + * + * Authors: plant/nerd73, Tiseno100 + * + * Copyright 2020 plant/nerd73. + * Copyright 2021 Tiseno100. */ #include #include diff --git a/src/chipset/opti391.c b/src/chipset/opti391.c index b787fae8f..4b9b8faff 100644 --- a/src/chipset/opti391.c +++ b/src/chipset/opti391.c @@ -1,18 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C391/392 chipset. + * Implementation of the OPTi 82C391/392 chipset. * - * Authors: Miran Grca, * - * Copyright 2021 Miran Grca. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. */ - #include #include #include diff --git a/src/chipset/opti495.c b/src/chipset/opti495.c index 627952d09..5eb5782e0 100644 --- a/src/chipset/opti495.c +++ b/src/chipset/opti495.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C493/82C495 chipset. + * Implementation of the OPTi 82C493/82C495 chipset. * * * - * Authors: Tiseno100, - * Miran Grca, + * Authors: Tiseno100, + * Miran Grca, * - * Copyright 2008-2020 Tiseno100. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Tiseno100. + * Copyright 2016-2020 Miran Grca. */ #include #include diff --git a/src/chipset/opti499.c b/src/chipset/opti499.c index 519b394a4..c033cd4f5 100644 --- a/src/chipset/opti499.c +++ b/src/chipset/opti499.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C493/82C499 chipset. + * Implementation of the OPTi 82C493/82C499 chipset. * * * - * Authors: Tiseno100, - * Miran Grca, + * Authors: Tiseno100, + * Miran Grca, * - * Copyright 2008-2020 Tiseno100. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Tiseno100. + * Copyright 2016-2020 Miran Grca. */ #include #include diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index 76989481e..fdcb4fc3e 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C546/82C547(Python) & 82C596/82C597(Cobra) chipsets. + * Implementation of the OPTi 82C546/82C547(Python) & 82C596/82C597(Cobra) chipsets. - * Authors: plant/nerd73, + * Authors: plant/nerd73, * Miran Grca, * Tiseno100 * - * Copyright 2020 plant/nerd73. - * Copyright 2020 Miran Grca. - * Copyright 2021 Tiseno100. + * Copyright 2020 plant/nerd73. + * Copyright 2020 Miran Grca. + * Copyright 2021 Tiseno100. */ #include #include @@ -35,7 +35,7 @@ typedef struct { uint8_t idx, is_pci, - regs[16]; + regs[16]; } opti5x7_t; #ifdef ENABLE_OPTI5X7_LOG diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index 2605c27b9..7db233935 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C822 VESA Local Bus to PCI - * Bridge Interface. + * Implementation of the OPTi 82C822 VESA Local Bus to PCI + * Bridge Interface. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2022 Miran Grca. + * Copyright 2022 Miran Grca. */ #include #include @@ -42,8 +42,8 @@ typedef struct { - uint8_t irq_convert, - pci_regs[256]; + uint8_t irq_convert, + pci_regs[256]; } opti822_t; // #define ENABLE_OPTI822_LOG 1 @@ -56,13 +56,13 @@ opti822_log(const char *fmt, ...) va_list ap; if (opti822_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define opti822_log(fmt, ...) +# define opti822_log(fmt, ...) #endif /* NOTE: We currently cheat and pass all PCI shadow RAM accesses to ISA as well. @@ -71,13 +71,13 @@ opti822_log(const char *fmt, ...) static void opti822_recalc(opti822_t *dev) { - int i, reg, bit_r, bit_w; - int state; + int i, reg, bit_r, bit_w; + int state; uint32_t base; for (i = 0; i < 12; i++) { - base = 0x000c0000 + (i << 14); - reg = 0x44 + ((i >> 2) ^ 3); + base = 0x000c0000 + (i << 14); + reg = 0x44 + ((i >> 2) ^ 3); bit_w = (i & 3); bit_r = bit_w + 4; bit_w = 1 << bit_w; @@ -99,19 +99,19 @@ static void opti822_update_irqs(opti822_t *dev, int set) { uint8_t val; - int i, reg; - int shift, irq; - int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; - pic_t *temp_pic; + int i, reg; + int shift, irq; + int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; + pic_t *temp_pic; // dev->irq_convert = (dev->pci_regs[0x53] & 0x08); dev->irq_convert = 1; for (i = 0; i < 16; i++) { - reg = 0x88 + (i >> 1); + reg = 0x88 + (i >> 1); shift = (i & 1) << 2; - val = (dev->pci_regs[reg] >> shift) & 0x0f; - irq = irq_map[val & 0x07]; + val = (dev->pci_regs[reg] >> shift) & 0x0f; + irq = irq_map[val & 0x07]; if (irq == -1) continue; temp_pic = (irq >= 8) ? &pic2 : &pic; @@ -127,8 +127,8 @@ static void opti822_pci_write(int func, int addr, uint8_t val, void *priv) { opti822_t *dev = (opti822_t *) priv; - int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; - int pin, slot; + int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; + int pin, slot; opti822_log("opti822_write(%02X, %02X, %02X)\n", func, addr, val); @@ -144,7 +144,7 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) /* Status Register */ case 0x06: if (!(dev->pci_regs[0x52] & 0x04)) - dev->pci_regs[addr] = (val & 0x80); + dev->pci_regs[addr] = (val & 0x80); break; case 0x07: dev->pci_regs[addr] &= ~(val & 0xf9); @@ -293,33 +293,33 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) dev->pci_regs[addr] = val; break; - case 0x88 ... 0x8f: - dev->pci_regs[addr] = val; - opti822_update_irqs(dev, 0); - irq = irq_map[val & 0x07]; - pin = 4 - ((addr & 0x01) << 1); - slot = ((addr & 0x06) >> 1); - if (irq >= 0) { - opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); - pci_set_irq_routing(pin + (slot << 2), irq); - pci_set_irq_level(pin + (slot << 2), !!(val & 0x07)); - } else { - opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); - pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); - } - irq = irq_map[(val >> 4) & 0x07]; - pin = 3 - ((addr & 0x01) << 1); - slot = ((addr & 0x06) >> 1); - if (irq >= 0) { - opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); - pci_set_irq_routing(pin + (slot << 2), irq); - pci_set_irq_level(pin + (slot << 2), !!((val >> 4) & 0x07)); - } else { - opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); - pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); - } - opti822_update_irqs(dev, 1); - break; + case 0x88 ... 0x8f: + dev->pci_regs[addr] = val; + opti822_update_irqs(dev, 0); + irq = irq_map[val & 0x07]; + pin = 4 - ((addr & 0x01) << 1); + slot = ((addr & 0x06) >> 1); + if (irq >= 0) { + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); + pci_set_irq_routing(pin + (slot << 2), irq); + pci_set_irq_level(pin + (slot << 2), !!(val & 0x07)); + } else { + opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); + pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); + } + irq = irq_map[(val >> 4) & 0x07]; + pin = 3 - ((addr & 0x01) << 1); + slot = ((addr & 0x06) >> 1); + if (irq >= 0) { + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); + pci_set_irq_routing(pin + (slot << 2), irq); + pci_set_irq_level(pin + (slot << 2), !!((val >> 4) & 0x07)); + } else { + opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); + pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); + } + opti822_update_irqs(dev, 1); + break; } } @@ -327,7 +327,7 @@ static uint8_t opti822_pci_read(int func, int addr, void *priv) { opti822_t *dev = (opti822_t *) priv; - uint8_t ret; + uint8_t ret; ret = 0xff; @@ -343,12 +343,14 @@ static void opti822_reset(void *priv) { opti822_t *dev = (opti822_t *) priv; - int i; + int i; memset(dev->pci_regs, 0, 256); - dev->pci_regs[0x00] = 0x45; dev->pci_regs[0x01] = 0x10; /*OPTi*/ - dev->pci_regs[0x02] = 0x22; dev->pci_regs[0x03] = 0xc8; /*82C822 PCIB*/ + dev->pci_regs[0x00] = 0x45; + dev->pci_regs[0x01] = 0x10; /*OPTi*/ + dev->pci_regs[0x02] = 0x22; + dev->pci_regs[0x03] = 0xc8; /*82C822 PCIB*/ dev->pci_regs[0x04] = 0x07; dev->pci_regs[0x06] = 0x80; dev->pci_regs[0x07] = 0x02; @@ -356,7 +358,8 @@ opti822_reset(void *priv) dev->pci_regs[0x0b] = 0x06; dev->pci_regs[0x0d] = 0x20; - dev->pci_regs[0x40] = 0x01; dev->pci_regs[0x41] = 0x0c; + dev->pci_regs[0x40] = 0x01; + dev->pci_regs[0x41] = 0x0c; dev->pci_regs[0x43] = 0x02; dev->pci_regs[0x52] = 0x06; dev->pci_regs[0x53] = 0x90; @@ -370,7 +373,7 @@ opti822_reset(void *priv) static void opti822_close(void *p) { - opti822_t *dev = (opti822_t *)p; + opti822_t *dev = (opti822_t *) p; free(dev); } diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index 95aaf4cb6..51ffc7430 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C802G/82C895 chipset. + * Implementation of the OPTi 82C802G/82C895 chipset. * * * - * Authors: Tiseno100, - * Miran Grca, + * Authors: Tiseno100, + * Miran Grca, * - * Copyright 2008-2020 Tiseno100. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Tiseno100. + * Copyright 2016-2020 Miran Grca. */ #include #include diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 5a30c3730..ec7381cec 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of VLSI 82C311 ("SCAMP") chipset. + * Emulation of VLSI 82C311 ("SCAMP") chipset. * - * Note: The datasheet mentions that the chipset supports up to 8MB - * of DRAM. This is intepreted as 'being able to refresh up to - * 8MB of DRAM chips', because it works fine with bus-based - * memory expansion. + * Note: The datasheet mentions that the chipset supports up to 8MB + * of DRAM. This is intepreted as 'being able to refresh up to + * 8MB of DRAM chips', because it works fine with bus-based + * memory expansion. * * * - * Authors: Sarah Walker, + * Authors: Sarah Walker, * - * Copyright 2020 Sarah Walker. + * Copyright 2020 Sarah Walker. */ #include #include diff --git a/src/chipset/scat.c b/src/chipset/scat.c index 7b5a1d37d..57b06662a 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Chips&Technology's SCAT (82C235) chipset. + * Implementation of Chips&Technology's SCAT (82C235) chipset. * - * Re-worked version based on the 82C235 datasheet and errata. + * Re-worked version based on the 82C235 datasheet and errata. * * * - * Authors: Original by GreatPsycho for PCem. - * Fred N. van Kempen, + * Authors: Original by GreatPsycho for PCem. + * Fred N. van Kempen, * - * Copyright 2017-2019 GreatPsycho. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2019 GreatPsycho. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index 7f5a22796..d13a1cf83 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -1,20 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the SiS 5511/5512/5513 Pentium PCI/ISA Chipset. + * Implementation of the SiS 5511/5512/5513 Pentium PCI/ISA Chipset. * * * - * Authors: Tiseno100, + * Authors: Tiseno100, * - * Copyright 2021 Tiseno100. + * Copyright 2021 Tiseno100. */ - #include #include #include diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 008ca5423..daf64aa74 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -1,18 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the SiS 5571 Chipset. + * Implementation of the SiS 5571 Chipset. * - * Authors: Tiseno100, * - * Copyright 2021 Tiseno100. + * + * Authors: Tiseno100, + * + * Copyright 2021 Tiseno100. */ - #include #include #include diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index e6e32c4b6..6a65e2d62 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the SiS 85c496/85c497 chip. + * Implementation of the SiS 85c496/85c497 chip. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2019,2020 Miran Grca. + * Copyright 2019-2020 Miran Grca. */ #include #include diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index 9b67c4466..ade5573f1 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -1,17 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the SiS 85c401/85c402, 85c460, 85c461, and - * 85c407/85c471 chipsets. + * Emulation of the SiS 85c401/85c402, 85c460, 85c461, and + * 85c407/85c471 chipsets. * - * Authors: Miran Grca, * - * Copyright 2019,2020 Miran Grca. + * + * Authors: Miran Grca, + * + * Copyright 2019,2020 Miran Grca. */ #include #include diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 06552c751..1aa5daead 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the SiS 85C50x Chipset. + * Implementation of the SiS 85C50x Chipset. * * * - * Authors: Tiseno100, - * Miran Grca, + * Authors: Tiseno100, + * Miran Grca, * - * Copyright 2020,2021 Tiseno100. - * Copyright 2020,2021 Miran Grca. + * Copyright 2020-2021 Tiseno100. + * Copyright 2020-2021 Miran Grca. */ #include #include diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index b36010699..cd13af3f0 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the STMicroelectronics STPC series of SoCs. + * Implementation of the STMicroelectronics STPC series of SoCs. * * * - * Authors: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index 47501dfb4..dea5ac99a 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -1,21 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the UMC 8886xx PCI to ISA Bridge . + * Implementation of the UMC 8886xx PCI to ISA Bridge . * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. * - * Authors: Tiseno100, - * Miran Grca, * - * Copyright 2021 Tiseno100. - * Copyright 2021 Miran Grca. + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2021 Tiseno100. + * Copyright 2021 Miran Grca. */ /* @@ -65,7 +67,6 @@ Function 1 Register 4: (UMC 8886AF/8886BF Only!) Bit 0: Enable Internal IDE */ - #include #include #include diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index 0179bdc72..40d17533b 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -1,24 +1,26 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the UMC HB4 "Super Energy Star Green" PCI Chipset. + * Implementation of the UMC HB4 "Super Energy Star Green" PCI Chipset. * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. * - * Note 2: Additional information were also used from all - * around the web. + * Note 2: Additional information were also used from all + * around the web. * - * Authors: Tiseno100, - * Miran Grca, * - * Copyright 2021 Tiseno100. - * Copyright 2021 Miran Grca. + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2021 Tiseno100. + * Copyright 2021 Miran Grca. */ /* diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index db137bc63..99802b2b5 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the VIA Apollo series of chips. + * Implementation of the VIA Apollo series of chips. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, - * Tiseno100, + * Authors: Sarah Walker, + * Miran Grca, + * Melissa Goad, + * Tiseno100, * - * Copyright 2020 Miran Grca. - * Copyright 2020 Melissa Goad. - * Copyright 2020 Tiseno100. + * Copyright 2020 Miran Grca. + * Copyright 2020 Melissa Goad. + * Copyright 2020 Tiseno100. */ #include #include diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 48cae7e41..e6701ebfc 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -1,24 +1,25 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of the VIA PIPC southbridges. + * This file is part of the 86Box distribution. + * + * Emulation of the VIA PIPC southbridges. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, - * RichardG, + * Authors: Sarah Walker, + * Miran Grca, + * Melissa Goad, + * RichardG, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2020 Melissa Goad. - * Copyright 2020-2021 RichardG. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2020 Melissa Goad. + * Copyright 2020-2021 RichardG. */ - #include #include #include diff --git a/src/chipset/via_vt82c49x.c b/src/chipset/via_vt82c49x.c index 7f413bb97..9bd5baf13 100644 --- a/src/chipset/via_vt82c49x.c +++ b/src/chipset/via_vt82c49x.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the VIA VT82C49X chipset. + * Implementation of the VIA VT82C49X chipset. * * * - * Authors: Tiseno100, - * Miran Grca, + * Authors: Tiseno100, + * Miran Grca, * - * Copyright 2020 Tiseno100. - * Copyright 2020 Miran Grca. + * Copyright 2020 Tiseno100. + * Copyright 2020 Miran Grca. */ #include #include diff --git a/src/chipset/via_vt82c505.c b/src/chipset/via_vt82c505.c index c6fed0144..76c533574 100644 --- a/src/chipset/via_vt82c505.c +++ b/src/chipset/via_vt82c505.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the VIA VT82C505 VL/PCI Bridge Controller. + * Implementation of the VIA VT82C505 VL/PCI Bridge Controller. * * * - * Authors: Tiseno100, - * Miran Grca, + * Authors: Tiseno100, + * Miran Grca, * - * Copyright 2020 Tiseno100. - * Copyright 2020 Miran Grca. + * Copyright 2020 Tiseno100. + * Copyright 2020 Miran Grca. */ #include #include diff --git a/src/chipset/vl82c480.c b/src/chipset/vl82c480.c index fa5bdce7e..9e1b9b8f7 100644 --- a/src/chipset/vl82c480.c +++ b/src/chipset/vl82c480.c @@ -1,16 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the VLSI VL82c480 chipset. + * Implementation of the VLSI VL82c480 chipset. * - * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. */ #include #include diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index e0cc171fb..41fad0418 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Western Digital WD76C10 chipset. + * Implementation of the Western Digital WD76C10 chipset. * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. * - * Authors: Tiseno100 * - * Copyright 2021 Tiseno100 * + * Authors: Tiseno100 + * + * Copyright 2021 Tiseno100 */ - #include #include #include diff --git a/src/codegen/CMakeLists.txt b/src/codegen/CMakeLists.txt index 416b4792a..23936959e 100644 --- a/src/codegen/CMakeLists.txt +++ b/src/codegen/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # if(DYNAREC) diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index f633243ca..f2d678067 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -9,28 +9,30 @@ #include "x86_ops.h" #include "codegen.h" -void (*codegen_timing_start)(); +void (*codegen_timing_start)(void); void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); -void (*codegen_timing_block_start)(); -void (*codegen_timing_block_end)(); -int (*codegen_timing_jump_cycles)(); +void (*codegen_timing_block_start)(void); +void (*codegen_timing_block_end)(void); +int (*codegen_timing_jump_cycles)(void); -void codegen_timing_set(codegen_timing_t *timing) +void +codegen_timing_set(codegen_timing_t *timing) { - codegen_timing_start = timing->start; - codegen_timing_prefix = timing->prefix; - codegen_timing_opcode = timing->opcode; - codegen_timing_block_start = timing->block_start; - codegen_timing_block_end = timing->block_end; - codegen_timing_jump_cycles = timing->jump_cycles; + codegen_timing_start = timing->start; + codegen_timing_prefix = timing->prefix; + codegen_timing_opcode = timing->opcode; + codegen_timing_block_start = timing->block_start; + codegen_timing_block_end = timing->block_end; + codegen_timing_jump_cycles = timing->jump_cycles; } int codegen_in_recompile; /* This is for compatibility with new x87 code. */ -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */ - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); + /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */ + cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); } diff --git a/src/codegen/codegen.h b/src/codegen/codegen.h index 4a154be2d..af602427d 100644 --- a/src/codegen/codegen.h +++ b/src/codegen/codegen.h @@ -41,11 +41,11 @@ #include "x86_ops.h" #ifdef __amd64__ -#include "codegen_x86-64.h" +# include "codegen_x86-64.h" #elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 -#include "codegen_x86.h" +# include "codegen_x86.h" #else -#error Dynamic recompiler not implemented on your platform +# error Dynamic recompiler not implemented on your platform #endif /*Handling self-modifying code (of which there is a lot on x86) : @@ -73,38 +73,37 @@ same page). */ -typedef struct codeblock_t -{ - uint64_t page_mask, page_mask2; - uint64_t *dirty_mask, *dirty_mask2; - uint64_t cmp; +typedef struct codeblock_t { + uint64_t page_mask, page_mask2; + uint64_t *dirty_mask, *dirty_mask2; + uint64_t cmp; - /*Previous and next pointers, for the codeblock list associated with - each physical page. Two sets of pointers, as a codeblock can be - present in two pages.*/ - struct codeblock_t *prev, *next; - struct codeblock_t *prev_2, *next_2; + /*Previous and next pointers, for the codeblock list associated with + each physical page. Two sets of pointers, as a codeblock can be + present in two pages.*/ + struct codeblock_t *prev, *next; + struct codeblock_t *prev_2, *next_2; - /*Pointers for codeblock tree, used to search for blocks when hash lookup - fails.*/ - struct codeblock_t *parent, *left, *right; + /*Pointers for codeblock tree, used to search for blocks when hash lookup + fails.*/ + struct codeblock_t *parent, *left, *right; - int pnt; - int ins; + int pnt; + int ins; int valid; - int was_recompiled; - int TOP; + int was_recompiled; + int TOP; - uint32_t pc; - uint32_t _cs; - uint32_t endpc; - uint32_t phys, phys_2; - uint32_t status; - uint32_t flags; + uint32_t pc; + uint32_t _cs; + uint32_t endpc; + uint32_t phys, phys_2; + uint32_t status; + uint32_t flags; - uint8_t data[2048]; + uint8_t data[2048]; } codeblock_t; /*Code block uses FPU*/ @@ -112,219 +111,192 @@ typedef struct codeblock_t /*Code block is always entered with the same FPU top-of-stack*/ #define CODEBLOCK_STATIC_TOP 2 -static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) +static inline codeblock_t * +codeblock_tree_find(uint32_t phys, uint32_t _cs) { - codeblock_t *block = pages[phys >> 12].head; - uint64_t a = _cs | ((uint64_t)phys << 32); + codeblock_t *block = pages[phys >> 12].head; + uint64_t a = _cs | ((uint64_t) phys << 32); - while (block) - { - if (a == block->cmp) - { - if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) - break; - } - if (a < block->cmp) - block = block->left; - else - block = block->right; - } - - return block; -} - -static inline void codeblock_tree_add(codeblock_t *new_block) -{ - codeblock_t *block = pages[new_block->phys >> 12].head; - uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); - new_block->cmp = a; - - if (!block) - { - pages[new_block->phys >> 12].head = new_block; - new_block->parent = new_block->left = new_block->right = NULL; + while (block) { + if (a == block->cmp) { + if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) + break; } + if (a < block->cmp) + block = block->left; else - { - codeblock_t *old_block = NULL; + block = block->right; + } - while (block) - { - old_block = block; - if (a < old_block->cmp) - block = block->left; - else - block = block->right; - } - - if (a < old_block->cmp) - old_block->left = new_block; - else - old_block->right = new_block; - - new_block->parent = old_block; - new_block->left = new_block->right = NULL; - } + return block; } -static inline void codeblock_tree_delete(codeblock_t *block) +static inline void +codeblock_tree_add(codeblock_t *new_block) { - codeblock_t *parent = block->parent; + codeblock_t *block = pages[new_block->phys >> 12].head; + uint64_t a = new_block->_cs | ((uint64_t) new_block->phys << 32); + new_block->cmp = a; - if (!block->left && !block->right) - { - /*Easy case - remove from parent*/ - if (!parent) - pages[block->phys >> 12].head = NULL; - else - { - if (parent->left == block) - parent->left = NULL; - if (parent->right == block) - parent->right = NULL; - } - return; - } - else if (!block->left) - { - /*Only right node*/ - if (!parent) - { - pages[block->phys >> 12].head = block->right; - pages[block->phys >> 12].head->parent = NULL; - } - else - { - if (parent->left == block) - { - parent->left = block->right; - parent->left->parent = parent; - } - if (parent->right == block) - { - parent->right = block->right; - parent->right->parent = parent; - } - } - return; - } - else if (!block->right) - { - /*Only left node*/ - if (!parent) - { - pages[block->phys >> 12].head = block->left; - pages[block->phys >> 12].head->parent = NULL; - } - else - { - if (parent->left == block) - { - parent->left = block->left; - parent->left->parent = parent; - } - if (parent->right == block) - { - parent->right = block->left; - parent->right->parent = parent; - } - } - return; + if (!block) { + pages[new_block->phys >> 12].head = new_block; + new_block->parent = new_block->left = new_block->right = NULL; + } else { + codeblock_t *old_block = NULL; + + while (block) { + old_block = block; + if (a < old_block->cmp) + block = block->left; + else + block = block->right; } + + if (a < old_block->cmp) + old_block->left = new_block; else - { - /*Difficult case - node has two children. Walk right child to find lowest node*/ - codeblock_t *lowest = block->right, *highest; - codeblock_t *old_parent; + old_block->right = new_block; - while (lowest->left) - lowest = lowest->left; - - old_parent = lowest->parent; - - /*Replace deleted node with lowest node*/ - if (!parent) - pages[block->phys >> 12].head = lowest; - else - { - if (parent->left == block) - parent->left = lowest; - if (parent->right == block) - parent->right = lowest; - } - - lowest->parent = parent; - lowest->left = block->left; - if (lowest->left) - lowest->left->parent = lowest; - - old_parent->left = NULL; - - highest = lowest->right; - if (!highest) - { - if (lowest != block->right) - { - lowest->right = block->right; - block->right->parent = lowest; - } - return; - } - - while (highest->right) - highest = highest->right; - - if (block->right && block->right != lowest) - { - highest->right = block->right; - block->right->parent = highest; - } - } + new_block->parent = old_block; + new_block->left = new_block->right = NULL; + } } -#define PAGE_MASK_INDEX_MASK 3 +static inline void +codeblock_tree_delete(codeblock_t *block) +{ + codeblock_t *parent = block->parent; + + if (!block->left && !block->right) { + /*Easy case - remove from parent*/ + if (!parent) + pages[block->phys >> 12].head = NULL; + else { + if (parent->left == block) + parent->left = NULL; + if (parent->right == block) + parent->right = NULL; + } + return; + } else if (!block->left) { + /*Only right node*/ + if (!parent) { + pages[block->phys >> 12].head = block->right; + pages[block->phys >> 12].head->parent = NULL; + } else { + if (parent->left == block) { + parent->left = block->right; + parent->left->parent = parent; + } + if (parent->right == block) { + parent->right = block->right; + parent->right->parent = parent; + } + } + return; + } else if (!block->right) { + /*Only left node*/ + if (!parent) { + pages[block->phys >> 12].head = block->left; + pages[block->phys >> 12].head->parent = NULL; + } else { + if (parent->left == block) { + parent->left = block->left; + parent->left->parent = parent; + } + if (parent->right == block) { + parent->right = block->left; + parent->right->parent = parent; + } + } + return; + } else { + /*Difficult case - node has two children. Walk right child to find lowest node*/ + codeblock_t *lowest = block->right, *highest; + codeblock_t *old_parent; + + while (lowest->left) + lowest = lowest->left; + + old_parent = lowest->parent; + + /*Replace deleted node with lowest node*/ + if (!parent) + pages[block->phys >> 12].head = lowest; + else { + if (parent->left == block) + parent->left = lowest; + if (parent->right == block) + parent->right = lowest; + } + + lowest->parent = parent; + lowest->left = block->left; + if (lowest->left) + lowest->left->parent = lowest; + + old_parent->left = NULL; + + highest = lowest->right; + if (!highest) { + if (lowest != block->right) { + lowest->right = block->right; + block->right->parent = lowest; + } + return; + } + + while (highest->right) + highest = highest->right; + + if (block->right && block->right != lowest) { + highest->right = block->right; + block->right->parent = highest; + } + } +} + +#define PAGE_MASK_INDEX_MASK 3 #define PAGE_MASK_INDEX_SHIFT 10 -#define PAGE_MASK_MASK 63 -#define PAGE_MASK_SHIFT 4 +#define PAGE_MASK_MASK 63 +#define PAGE_MASK_SHIFT 4 extern codeblock_t *codeblock; extern codeblock_t **codeblock_hash; -void codegen_init(); -void codegen_reset(); -void codegen_block_init(uint32_t phys_addr); -void codegen_block_remove(); -void codegen_block_start_recompile(codeblock_t *block); -void codegen_block_end_recompile(codeblock_t *block); -void codegen_block_end(); -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); -void codegen_generate_seg_restore(); -void codegen_set_op32(); -void codegen_flush(); -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr); +extern void codegen_init(void); +extern void codegen_reset(void); +extern void codegen_block_init(uint32_t phys_addr); +extern void codegen_block_remove(void); +extern void codegen_block_start_recompile(codeblock_t *block); +extern void codegen_block_end_recompile(codeblock_t *block); +extern void codegen_block_end(void); +extern void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); +extern void codegen_generate_seg_restore(void); +extern void codegen_set_op32(void); +extern void codegen_flush(void); +extern void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr); -extern int cpu_block_end; +extern int cpu_block_end; extern uint32_t codegen_endpc; extern int codegen_block_cycles; -extern void (*codegen_timing_start)(); +extern void (*codegen_timing_start)(void); extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); -extern void (*codegen_timing_block_start)(); -extern void (*codegen_timing_block_end)(); -extern int (*codegen_timing_jump_cycles)(); +extern void (*codegen_timing_block_start)(void); +extern void (*codegen_timing_block_end)(void); +extern int (*codegen_timing_jump_cycles)(void); -typedef struct codegen_timing_t -{ - void (*start)(); - void (*prefix)(uint8_t prefix, uint32_t fetchdat); - void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); - void (*block_start)(); - void (*block_end)(); - int (*jump_cycles)(); +typedef struct codegen_timing_t { + void (*start)(void); + void (*prefix)(uint8_t prefix, uint32_t fetchdat); + void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); + void (*block_start)(void); + void (*block_end)(void); + int (*jump_cycles)(void); } codegen_timing_t; extern codegen_timing_t codegen_timing_pentium; @@ -342,53 +314,53 @@ extern int block_pos; #define CPU_BLOCK_END() cpu_block_end = 1 -static inline void addbyte(uint8_t val) +static inline void +addbyte(uint8_t val) { - codeblock[block_current].data[block_pos++] = val; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } + codeblock[block_current].data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) { + CPU_BLOCK_END(); + } } -static inline void addword(uint16_t val) +static inline void +addword(uint16_t val) { uint16_t *p = (uint16_t *) &codeblock[block_current].data[block_pos]; - *p = val; - block_pos += 2; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } + *p = val; + block_pos += 2; + if (block_pos >= BLOCK_MAX) { + CPU_BLOCK_END(); + } } -static inline void addlong(uint32_t val) +static inline void +addlong(uint32_t val) { uint32_t *p = (uint32_t *) &codeblock[block_current].data[block_pos]; - *p = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } + *p = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) { + CPU_BLOCK_END(); + } } -static inline void addquad(uint64_t val) +static inline void +addquad(uint64_t val) { uint64_t *p = (uint64_t *) &codeblock[block_current].data[block_pos]; - *p = val; - block_pos += 8; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } + *p = val; + block_pos += 8; + if (block_pos >= BLOCK_MAX) { + CPU_BLOCK_END(); + } } /*Current physical page of block being recompiled. -1 if no recompilation taking place */ extern uint32_t recomp_page; -extern x86seg *op_ea_seg; -extern int op_ssegs; +extern x86seg *op_ea_seg; +extern int op_ssegs; extern uint32_t op_old_pc; /*Set to 1 if flags have been changed in the block being recompiled, and hence diff --git a/src/codegen/codegen_accumulate.h b/src/codegen/codegen_accumulate.h index b1e64db18..3e8261748 100644 --- a/src/codegen/codegen_accumulate.h +++ b/src/codegen/codegen_accumulate.h @@ -1,12 +1,11 @@ -enum -{ - ACCREG_cycles = 0, +enum { + ACCREG_cycles = 0, - ACCREG_COUNT + ACCREG_COUNT }; struct ir_data_t; void codegen_accumulate(int acc_reg, int delta); void codegen_accumulate_flush(void); -void codegen_accumulate_reset(); +void codegen_accumulate_reset(void); diff --git a/src/codegen/codegen_accumulate_x86-64.c b/src/codegen/codegen_accumulate_x86-64.c index ceb751a95..6e88487ba 100644 --- a/src/codegen/codegen_accumulate_x86-64.c +++ b/src/codegen/codegen_accumulate_x86-64.c @@ -9,59 +9,61 @@ static struct { - int count; - uintptr_t dest_reg; -} acc_regs[] = -{ - [ACCREG_cycles] = {0, (uintptr_t) &(cycles)}, + int count; + uintptr_t dest_reg; +} acc_regs[] = { + [ACCREG_cycles] = {0, (uintptr_t) & (cycles)}, }; -void codegen_accumulate(int acc_reg, int delta) +void +codegen_accumulate(int acc_reg, int delta) { - acc_regs[acc_reg].count += delta; + acc_regs[acc_reg].count += delta; #ifdef USE_ACYCS - if ((acc_reg == ACCREG_cycles) && (delta != 0)) { - if (delta == -1) { - /* -delta = 1 */ - addbyte(0xff); /*inc dword ptr[&acycs]*/ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &(acycs)); - } else if (delta == 1) { - /* -delta = -1 */ - addbyte(0xff); /*dec dword ptr[&acycs]*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &(acycs)); - } else { - addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &(acycs)); - addlong(-delta); - } - } + if ((acc_reg == ACCREG_cycles) && (delta != 0)) { + if (delta == -1) { + /* -delta = 1 */ + addbyte(0xff); /*inc dword ptr[&acycs]*/ + addbyte(0x04); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) & (acycs)); + } else if (delta == 1) { + /* -delta = -1 */ + addbyte(0xff); /*dec dword ptr[&acycs]*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) & (acycs)); + } else { + addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ + addbyte(0x04); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) & (acycs)); + addlong(-delta); + } + } #endif } -void codegen_accumulate_flush(void) +void +codegen_accumulate_flush(void) { - if (acc_regs[0].count) { - /* To reduce the size of the generated code, we take advantage of - the fact that the target offset points to _cycles within cpu_state, - so we can just use our existing infrastracture for variables - relative to cpu_state. */ - addbyte(0x81); /*ADDL $acc_regs[0].count,(_cycles)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(acc_regs[0].count); - } + if (acc_regs[0].count) { + /* To reduce the size of the generated code, we take advantage of + the fact that the target offset points to _cycles within cpu_state, + so we can just use our existing infrastracture for variables + relative to cpu_state. */ + addbyte(0x81); /*ADDL $acc_regs[0].count,(_cycles)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addlong(acc_regs[0].count); + } - acc_regs[0].count = 0; + acc_regs[0].count = 0; } -void codegen_accumulate_reset() +void +codegen_accumulate_reset(void) { - acc_regs[0].count = 0; + acc_regs[0].count = 0; } diff --git a/src/codegen/codegen_accumulate_x86.c b/src/codegen/codegen_accumulate_x86.c index b47c643d2..8d56c4c14 100644 --- a/src/codegen/codegen_accumulate_x86.c +++ b/src/codegen/codegen_accumulate_x86.c @@ -9,56 +9,58 @@ static struct { - int count; - uintptr_t dest_reg; -} acc_regs[] = -{ - [ACCREG_cycles] = {0, (uintptr_t) &(cycles)} + int count; + uintptr_t dest_reg; +} acc_regs[] = { + [ACCREG_cycles] = {0, (uintptr_t) & (cycles)} }; -void codegen_accumulate(int acc_reg, int delta) +void +codegen_accumulate(int acc_reg, int delta) { - acc_regs[acc_reg].count += delta; + acc_regs[acc_reg].count += delta; #ifdef USE_ACYCS - if ((acc_reg == ACCREG_cycles) && (delta != 0)) { - if (delta == -1) { - /* -delta = 1 */ - addbyte(0xff); /*inc dword ptr[&acycs]*/ - addbyte(0x05); - addlong((uint32_t) (uintptr_t) &(acycs)); - } else if (delta == 1) { - /* -delta = -1 */ - addbyte(0xff); /*dec dword ptr[&acycs]*/ - addbyte(0x0d); - addlong((uint32_t) (uintptr_t) &(acycs)); - } else { - addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ - addbyte(0x05); - addlong((uint32_t) (uintptr_t) &(acycs)); - addlong((uintptr_t) -delta); - } - } + if ((acc_reg == ACCREG_cycles) && (delta != 0)) { + if (delta == -1) { + /* -delta = 1 */ + addbyte(0xff); /*inc dword ptr[&acycs]*/ + addbyte(0x05); + addlong((uint32_t) (uintptr_t) & (acycs)); + } else if (delta == 1) { + /* -delta = -1 */ + addbyte(0xff); /*dec dword ptr[&acycs]*/ + addbyte(0x0d); + addlong((uint32_t) (uintptr_t) & (acycs)); + } else { + addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ + addbyte(0x05); + addlong((uint32_t) (uintptr_t) & (acycs)); + addlong((uintptr_t) -delta); + } + } #endif } -void codegen_accumulate_flush(void) +void +codegen_accumulate_flush(void) { - if (acc_regs[0].count) { - /* To reduce the size of the generated code, we take advantage of - the fact that the target offset points to _cycles within cpu_state, - so we can just use our existing infrastracture for variables - relative to cpu_state. */ - addbyte(0x81); /*MOVL $acc_regs[0].count,(_cycles)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(acc_regs[0].count); - } + if (acc_regs[0].count) { + /* To reduce the size of the generated code, we take advantage of + the fact that the target offset points to _cycles within cpu_state, + so we can just use our existing infrastracture for variables + relative to cpu_state. */ + addbyte(0x81); /*MOVL $acc_regs[0].count,(_cycles)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addlong(acc_regs[0].count); + } - acc_regs[0].count = 0; + acc_regs[0].count = 0; } -void codegen_accumulate_reset() +void +codegen_accumulate_reset(void) { - acc_regs[0].count = 0; + acc_regs[0].count = 0; } diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index aedeb88a9..dc5c9c4ae 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -16,9 +16,9 @@ #include "codegen_ops.h" #if defined __amd64__ || defined _M_X64 -#include "codegen_ops_x86-64.h" +# include "codegen_ops_x86-64.h" #elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include "codegen_ops_x86.h" +# include "codegen_ops_x86.h" #endif #include "codegen_ops_arith.h" @@ -32,8 +32,8 @@ #include "codegen_ops_stack.h" #include "codegen_ops_xchg.h" -RecompOpFn recomp_opcodes[512] = -{ +RecompOpFn recomp_opcodes[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, @@ -77,10 +77,11 @@ RecompOpFn recomp_opcodes[512] = /*d0*/ ropD0, ropD1_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_l, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_32 + // clang-format on }; -RecompOpFn recomp_opcodes_0f[512] = -{ +RecompOpFn recomp_opcodes_0f[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -124,11 +125,11 @@ RecompOpFn recomp_opcodes_0f[512] = /*d0*/ NULL, ropPSRLW, ropPSRLD, ropPSRLQ, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, ropPSRAW, ropPSRAD, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, /*f0*/ NULL, ropPSLLW, ropPSLLD, ropPSLLQ, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, + // clang-format on }; - -RecompOpFn recomp_opcodes_d8[512] = -{ +RecompOpFn recomp_opcodes_d8[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, @@ -172,10 +173,11 @@ RecompOpFn recomp_opcodes_d8[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, /*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, + // clang-format on }; -RecompOpFn recomp_opcodes_d9[512] = -{ +RecompOpFn recomp_opcodes_d9[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -219,10 +221,11 @@ RecompOpFn recomp_opcodes_d9[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_da[512] = -{ +RecompOpFn recomp_opcodes_da[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, @@ -266,10 +269,11 @@ RecompOpFn recomp_opcodes_da[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_db[512] = -{ +RecompOpFn recomp_opcodes_db[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -313,10 +317,11 @@ RecompOpFn recomp_opcodes_db[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_dc[512] = -{ +RecompOpFn recomp_opcodes_dc[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, @@ -360,10 +365,11 @@ RecompOpFn recomp_opcodes_dc[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, + // clang-format on }; -RecompOpFn recomp_opcodes_dd[512] = -{ +RecompOpFn recomp_opcodes_dd[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -407,10 +413,11 @@ RecompOpFn recomp_opcodes_dd[512] = /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_de[512] = -{ +RecompOpFn recomp_opcodes_de[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, @@ -454,10 +461,11 @@ RecompOpFn recomp_opcodes_de[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, /*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, + // clang-format on }; -RecompOpFn recomp_opcodes_df[512] = -{ +RecompOpFn recomp_opcodes_df[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -501,10 +509,11 @@ RecompOpFn recomp_opcodes_df[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_REPE[512] = -{ +RecompOpFn recomp_opcodes_REPE[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -548,10 +557,11 @@ RecompOpFn recomp_opcodes_REPE[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_REPNE[512] = -{ +RecompOpFn recomp_opcodes_REPNE[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -595,4 +605,5 @@ RecompOpFn recomp_opcodes_REPNE[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; diff --git a/src/codegen/codegen_ops.h b/src/codegen/codegen_ops.h index fe54cb9a4..f92ba4f6d 100644 --- a/src/codegen/codegen_ops.h +++ b/src/codegen/codegen_ops.h @@ -26,21 +26,21 @@ extern RecompOpFn recomp_opcodes_REPNE[512]; #define REG_EBP 5 #define REG_ESI 6 #define REG_EDI 7 -#define REG_AX 0 -#define REG_CX 1 -#define REG_DX 2 -#define REG_BX 3 -#define REG_SP 4 -#define REG_BP 5 -#define REG_SI 6 -#define REG_DI 7 -#define REG_AL 0 -#define REG_AH 4 -#define REG_CL 1 -#define REG_CH 5 -#define REG_DL 2 -#define REG_DH 6 -#define REG_BL 3 -#define REG_BH 7 +#define REG_AX 0 +#define REG_CX 1 +#define REG_DX 2 +#define REG_BX 3 +#define REG_SP 4 +#define REG_BP 5 +#define REG_SI 6 +#define REG_DI 7 +#define REG_AL 0 +#define REG_AH 4 +#define REG_CL 1 +#define REG_CH 5 +#define REG_DL 2 +#define REG_DH 6 +#define REG_BL 3 +#define REG_BH 7 #endif diff --git a/src/codegen/codegen_ops_arith.h b/src/codegen/codegen_ops_arith.h index 2e497f17c..f1c426838 100644 --- a/src/codegen/codegen_ops_arith.h +++ b/src/codegen/codegen_ops_arith.h @@ -1,1032 +1,956 @@ -static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - host_reg = LOAD_REG_W(opcode & 7); + host_reg = LOAD_REG_W(opcode & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - // ADD_HOST_REG_IMM_W(host_reg, 1); - INC_HOST_REG_W(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + // ADD_HOST_REG_IMM_W(host_reg, 1); + INC_HOST_REG_W(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); - codegen_flags_changed = 1; + codegen_flags_changed = 1; - return op_pc; + return op_pc; } -static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - host_reg = LOAD_REG_L(opcode & 7); + host_reg = LOAD_REG_L(opcode & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - // ADD_HOST_REG_IMM(host_reg, 1); - INC_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + // ADD_HOST_REG_IMM(host_reg, 1); + INC_HOST_REG(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); - codegen_flags_changed = 1; + codegen_flags_changed = 1; - return op_pc; + return op_pc; } -static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - host_reg = LOAD_REG_W(opcode & 7); + host_reg = LOAD_REG_W(opcode & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - // SUB_HOST_REG_IMM_W(host_reg, 1); - DEC_HOST_REG_W(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + // SUB_HOST_REG_IMM_W(host_reg, 1); + DEC_HOST_REG_W(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); - codegen_flags_changed = 1; + codegen_flags_changed = 1; - return op_pc; + return op_pc; } -static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - host_reg = LOAD_REG_L(opcode & 7); + host_reg = LOAD_REG_L(opcode & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - // SUB_HOST_REG_IMM(host_reg, 1); - DEC_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + // SUB_HOST_REG_IMM(host_reg, 1); + DEC_HOST_REG(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); - codegen_flags_changed = 1; + codegen_flags_changed = 1; - return op_pc; + return op_pc; } -#define ROP_ARITH_RMW(name, op, writeback) \ - static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } +#define ROP_ARITH_RMW(name, op, writeback) \ + static uint32_t rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \ + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_B_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_W(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \ + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_W_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_L(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \ + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_L_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } -#define ROP_ARITH_RM(name, op, writeback) \ - static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_B_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_W_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_L_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } +#define ROP_ARITH_RM(name, op, writeback) \ + static uint32_t rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_B(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_B_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_W(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_W_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_L(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_L_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } ROP_ARITH_RMW(ADD, ADD, 1) ROP_ARITH_RMW(SUB, SUB, 1) ROP_ARITH_RM(ADD, ADD, 1) ROP_ARITH_RM(SUB, SUB, 1) -static uint32_t ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - src_reg = 0; - } + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_B(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_B(target_seg); + src_reg = 0; + } - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -static uint32_t ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - src_reg = 0; - } + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_W(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_W(target_seg); + src_reg = 0; + } - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -static uint32_t ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - src_reg = 0; - } + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_L(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_L(target_seg); + src_reg = 0; + } - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -static uint32_t ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_B(fetchdat & 7); + if ((fetchdat & 0xc0) == 0xc0) { + dst_reg = LOAD_REG_B(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_B(target_seg); + dst_reg = 0; + } + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int src_reg, dst_reg; + + if ((fetchdat & 0xc0) == 0xc0) { + dst_reg = LOAD_REG_W(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_W(target_seg); + dst_reg = 0; + } + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int src_reg, dst_reg; + + if ((fetchdat & 0xc0) == 0xc0) { + dst_reg = LOAD_REG_L(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_L(target_seg); + dst_reg = 0; + } + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +static uint32_t +ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; +} +static uint32_t +ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + fetchdat = fastreadl(cs + op_pc); + ADD_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 4; +} + +static uint32_t +ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; +} +static uint32_t +ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + fetchdat = fastreadl(cs + op_pc); + host_reg = CMP_HOST_REG_IMM_L(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 4; +} + +static uint32_t +ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; +} +static uint32_t +ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + fetchdat = fastreadl(cs + op_pc); + SUB_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 4; +} + +static uint32_t +rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) + return 0; + + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_B(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE(target_seg); + host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - dst_reg = 0; + imm = fastreadb(cs + op_pc + 1); + } else { + host_reg = LOAD_REG_B(fetchdat & 7); + imm = (fetchdat >> 8) & 0xff; + } + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_B(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD8); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm | 0xffffff00); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_B(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_B(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + break; + } + + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_B_RELEASE(host_reg); } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - dst_reg = 0; - } \ - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - dst_reg = 0; - } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} - - -static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - fetchdat = fastreadl(cs + op_pc); - ADD_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 4; -} - -static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); + } else RELEASE_REG(host_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 2; } -static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); +static uint32_t +rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) + return 0; + + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_W(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_W(target_seg); + host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); + } + imm = fastreadw(cs + op_pc + 1); + } else { + host_reg = LOAD_REG_W(fetchdat & 7); + imm = (fetchdat >> 8) & 0xffff; + } + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD16); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + break; + } + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_W_RELEASE(host_reg); + } + } else RELEASE_REG(host_reg); - codegen_flags_changed = 1; - return op_pc + 2; + codegen_flags_changed = 1; + return op_pc + 3; } -static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_L(REG_EAX); + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - fetchdat = fastreadl(cs + op_pc); - host_reg = CMP_HOST_REG_IMM_L(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); + if ((fetchdat & 0x30) == 0x10) + return 0; + + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_L(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE(target_seg); + host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); + } + } else { + host_reg = LOAD_REG_L(fetchdat & 7); + } + imm = fastreadl(cs + op_pc + 1); + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD32); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + break; + } + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_L_RELEASE(host_reg); + } + } else RELEASE_REG(host_reg); - codegen_flags_changed = 1; - return op_pc + 4; + codegen_flags_changed = 1; + return op_pc + 5; } -static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_B(REG_AL); + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); + if ((fetchdat & 0x30) == 0x10) + return 0; - codegen_flags_changed = 1; - return op_pc + 1; + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_W(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_W(target_seg); + host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); + } + imm = fastreadb(cs + op_pc + 1); + } else { + host_reg = LOAD_REG_W(fetchdat & 7); + imm = (fetchdat >> 8) & 0xff; + } + + if (imm & 0x80) + imm |= 0xff80; + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD16); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + break; + } + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_W_RELEASE(host_reg); + } + } else + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; } -static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_W(REG_AX); + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); + if ((fetchdat & 0x30) == 0x10) + return 0; - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - fetchdat = fastreadl(cs + op_pc); - SUB_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 4; -} - -static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_B(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_B(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffffff00); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - break; - } - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_B_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} - -static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - imm = fastreadw(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xffff; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - } - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_W_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 3; -} -static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - } - else - { - host_reg = LOAD_REG_L(fetchdat & 7); - } - imm = fastreadl(cs + op_pc + 1); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - } - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_L_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 5; -} - -static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - if (imm & 0x80) - imm |= 0xff80; - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - } - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_W_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_L(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_L(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - if (imm & 0x80) - imm |= 0xffffff80; - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - } - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_L_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_L(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_L(target_seg); + host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); + } + imm = fastreadb(cs + op_pc + 1); + } else { + host_reg = LOAD_REG_L(fetchdat & 7); + imm = (fetchdat >> 8) & 0xff; + } + + if (imm & 0x80) + imm |= 0xffffff80; + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD32); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + break; + } + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_L_RELEASE(host_reg); + } + } else + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; } diff --git a/src/codegen/codegen_ops_fpu.h b/src/codegen/codegen_ops_fpu.h index 930e0182c..58a5adf7d 100644 --- a/src/codegen/codegen_ops_fpu.h +++ b/src/codegen/codegen_ops_fpu.h @@ -1,256 +1,268 @@ -static uint32_t ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); + FP_ENTER(); - FP_FXCH(opcode & 7); + FP_FXCH(opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); + FP_ENTER(); - FP_FLD(opcode & 7); + FP_FLD(opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); + FP_ENTER(); - FP_FST(opcode & 7); + FP_FST(opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); + FP_ENTER(); - FP_FST(opcode & 7); - FP_POP(); + FP_FST(opcode & 7); + FP_POP(); - return op_pc; + return op_pc; } - -static uint32_t ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_L(target_seg); - FP_LOAD_S(); + FP_LOAD_S(); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_Q(target_seg); - FP_LOAD_D(); + FP_LOAD_D(); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_W(target_seg); - FP_LOAD_IW(); + FP_LOAD_IW(); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_L(target_seg); - FP_LOAD_IL(); + FP_LOAD_IL(); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_Q(target_seg); - FP_LOAD_IQ(); + FP_LOAD_IQ(); - codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1; + codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1; - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg; + x86seg *target_seg; + int host_reg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - host_reg = FP_LOAD_REG(0); + host_reg = FP_LOAD_REG(0); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - MEM_STORE_ADDR_EA_L(target_seg, host_reg); + MEM_STORE_ADDR_EA_L(target_seg, host_reg); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg1, host_reg2 = 0; + x86seg *target_seg; + int host_reg1, host_reg2 = 0; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - FP_LOAD_REG_D(0, &host_reg1, &host_reg2); + FP_LOAD_REG_D(0, &host_reg1, &host_reg2); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 7); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 7); - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); + MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block); + uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block); - FP_POP(); + FP_POP(); - return new_pc; + return new_pc; } -static uint32_t ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block); + uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block); - FP_POP(); + FP_POP(); - return new_pc; + return new_pc; } -#define ropFarith(name, size, load, op) \ -static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(FPU_ ## name); \ - \ - return op_pc + 1; \ -} +#define ropFarith(name, size, load, op) \ + static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + x86seg *target_seg; \ + \ + FP_ENTER(); \ + op_pc--; \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + load(target_seg); \ + \ + op(FPU_##name); \ + \ + return op_pc + 1; \ + } -ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -#define ropFcompare(name, size, load, op) \ -static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(); \ - \ - return op_pc + 1; \ -} \ -static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t new_pc = ropF ## name ## size(opcode, fetchdat, op_32, op_pc, block); \ - \ - FP_POP(); \ - \ - return new_pc; \ -} +#define ropFcompare(name, size, load, op) \ + static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + x86seg *target_seg; \ + \ + FP_ENTER(); \ + op_pc--; \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + load(target_seg); \ + \ + op(); \ + \ + return op_pc + 1; \ + } \ + static uint32_t ropF##name##P##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + uint32_t new_pc = ropF##name##size(opcode, fetchdat, op_32, op_pc, block); \ + \ + FP_POP(); \ + \ + return new_pc; \ + } ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S); ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D); @@ -326,320 +338,346 @@ static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return op_pc + 1; }*/ - -static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_ADD, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_ADD, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_COMPARE_REG(0, opcode & 7); + FP_ENTER(); + FP_COMPARE_REG(0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIV, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_DIV, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIVR, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_DIVR, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_MUL, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_MUL, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUB, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_SUB, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUBR, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_SUBR, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_ADD, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_ADD, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIV, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_DIV, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIVR, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_DIVR, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_MUL, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_MUL, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUB, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_SUB, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUBR, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_SUBR, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_ADD, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_ADD, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_COMPARE_REG(0, opcode & 7); - FP_POP(); + FP_ENTER(); + FP_COMPARE_REG(0, opcode & 7); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIV, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_DIV, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIVR, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_DIVR, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_MUL, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_MUL, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUB, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_SUB, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUBR, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_SUBR, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_COMPARE_REG(0, 1); - FP_POP2(); + FP_ENTER(); + FP_COMPARE_REG(0, 1); + FP_POP2(); - return op_pc; + return op_pc; } -static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - FP_ENTER(); - host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs); - STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); + FP_ENTER(); + host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxs); + STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); - return op_pc; + return op_pc; } - -static uint32_t ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg; + x86seg *target_seg; + int host_reg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - host_reg = FP_LOAD_REG_INT_W(0); + host_reg = FP_LOAD_REG_INT_W(0); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - MEM_STORE_ADDR_EA_W(target_seg, host_reg); + MEM_STORE_ADDR_EA_W(target_seg, host_reg); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg; + x86seg *target_seg; + int host_reg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - host_reg = FP_LOAD_REG_INT(0); + host_reg = FP_LOAD_REG_INT(0); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - MEM_STORE_ADDR_EA_L(target_seg, host_reg); + MEM_STORE_ADDR_EA_L(target_seg, host_reg); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block); + uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block); - FP_POP(); + FP_POP(); - return new_pc; + return new_pc; } -static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block); + uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block); - FP_POP(); + FP_POP(); - return new_pc; + return new_pc; } -static uint32_t ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg1, host_reg2; + x86seg *target_seg; + int host_reg1, host_reg2; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2); + FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); + MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - FP_POP(); + FP_POP(); - return op_pc + 1; + return op_pc + 1; } - -static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - CHECK_SEG_READ(target_seg); + CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); - STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0); - UPDATE_NPXC(0); + MEM_LOAD_ADDR_EA_W(target_seg); + STORE_HOST_REG_ADDR_W((uintptr_t) &cpu_state.npxc, 0); + UPDATE_NPXC(0); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; - x86seg *target_seg; + int host_reg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxc); - MEM_STORE_ADDR_EA_W(target_seg, host_reg); + host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxc); + MEM_STORE_ADDR_EA_W(target_seg, host_reg); - return op_pc + 1; + return op_pc + 1; } - -static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_FCHS(); + FP_ENTER(); + FP_FCHS(); - return op_pc; + return op_pc; } -#define opFLDimm(name, v) \ - static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - static double fp_imm = v; \ - \ - FP_ENTER(); \ - FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \ - \ - return op_pc; \ - } +#define opFLDimm(name, v) \ + static uint32_t ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + static double fp_imm = v; \ + \ + FP_ENTER(); \ + FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \ + \ + return op_pc; \ + } opFLDimm(1, 1.0) -opFLDimm(L2T, 3.3219280948873623) -opFLDimm(L2E, 1.4426950408889634); + opFLDimm(L2T, 3.3219280948873623) + opFLDimm(L2E, 1.4426950408889634); opFLDimm(PI, 3.141592653589793); opFLDimm(EG2, 0.3010299956639812); opFLDimm(Z, 0.0) -static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) + static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull); + FP_ENTER(); + FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull); - return op_pc; + return op_pc; } diff --git a/src/codegen/codegen_ops_jump.h b/src/codegen/codegen_ops_jump.h index 54e51f150..f5c66dd1b 100644 --- a/src/codegen/codegen_ops_jump.h +++ b/src/codegen/codegen_ops_jump.h @@ -1,257 +1,258 @@ -static uint32_t ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fetchdat & 0xff; + uint32_t offset = fetchdat & 0xff; - if (offset & 0x80) - offset |= 0xffffff00; + if (offset & 0x80) + offset |= 0xffffff00; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+1+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 1 + offset); - return -1; + return -1; } -static uint32_t ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t offset = fetchdat & 0xffff; + uint16_t offset = fetchdat & 0xffff; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, (op_pc + 2 + offset) & 0xffff); - return -1; + return -1; } -static uint32_t ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fastreadl(cs + op_pc); + uint32_t offset = fastreadl(cs + op_pc); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 4 + offset); - return -1; + return -1; } - -static uint32_t ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fetchdat & 0xff; + uint32_t offset = fetchdat & 0xff; - if (offset & 0x80) - offset |= 0xffffff00; + if (offset & 0x80) + offset |= 0xffffff00; - if (op_32 & 0x200) - { - int host_reg = LOAD_REG_L(REG_ECX); - TEST_ZERO_JUMP_L(host_reg, op_pc+1+offset, 0); - } - else - { - int host_reg = LOAD_REG_W(REG_CX); - TEST_ZERO_JUMP_W(host_reg, op_pc+1+offset, 0); - } + if (op_32 & 0x200) { + int host_reg = LOAD_REG_L(REG_ECX); + TEST_ZERO_JUMP_L(host_reg, op_pc + 1 + offset, 0); + } else { + int host_reg = LOAD_REG_W(REG_CX); + TEST_ZERO_JUMP_W(host_reg, op_pc + 1 + offset, 0); + } - return op_pc+1; + return op_pc + 1; } -static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fetchdat & 0xff; + uint32_t offset = fetchdat & 0xff; - if (offset & 0x80) - offset |= 0xffffff00; + if (offset & 0x80) + offset |= 0xffffff00; - if (op_32 & 0x200) - { - int host_reg = LOAD_REG_L(REG_ECX); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_REG_L_RELEASE(host_reg); - TEST_NONZERO_JUMP_L(host_reg, op_pc+1+offset, 0); - } - else - { - int host_reg = LOAD_REG_W(REG_CX); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_REG_W_RELEASE(host_reg); - TEST_NONZERO_JUMP_W(host_reg, op_pc+1+offset, 0); - } + if (op_32 & 0x200) { + int host_reg = LOAD_REG_L(REG_ECX); + SUB_HOST_REG_IMM(host_reg, 1); + STORE_REG_L_RELEASE(host_reg); + TEST_NONZERO_JUMP_L(host_reg, op_pc + 1 + offset, 0); + } else { + int host_reg = LOAD_REG_W(REG_CX); + SUB_HOST_REG_IMM(host_reg, 1); + STORE_REG_W_RELEASE(host_reg); + TEST_NONZERO_JUMP_W(host_reg, op_pc + 1 + offset, 0); + } - return op_pc+1; + return op_pc + 1; } -static void BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - CALL_FUNC((uintptr_t)CF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); + CALL_FUNC((uintptr_t) CF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); } -static void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - int host_reg; + int host_reg; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - if (not) - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res); + if (not ) + TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + else + TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + break; - case FLAGS_UNKNOWN: - CALL_FUNC((uintptr_t)ZF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - break; - } + case FLAGS_UNKNOWN: + CALL_FUNC((uintptr_t) ZF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + break; + } } -static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - CALL_FUNC((uintptr_t)VF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); + CALL_FUNC((uintptr_t) VF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); } -static void BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - CALL_FUNC((uintptr_t)PF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); + CALL_FUNC((uintptr_t) PF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); } -static void BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - int host_reg; + int host_reg; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x80); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: + host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res); + AND_HOST_REG_IMM(host_reg, 0x80); + if (not ) + TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + break; - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x8000); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: + host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res); + AND_HOST_REG_IMM(host_reg, 0x8000); + if (not ) + TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + break; - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x80000000); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: + host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res); + AND_HOST_REG_IMM(host_reg, 0x80000000); + if (not ) + TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + break; - case FLAGS_UNKNOWN: - CALL_FUNC((uintptr_t)NF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - break; - } + case FLAGS_UNKNOWN: + CALL_FUNC((uintptr_t) NF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + break; + } } +#define ropBRANCH(name, func, not ) \ + static uint32_t rop##name(uint8_t opcode, uint32_t fetchdat, \ + uint32_t op_32, uint32_t op_pc, \ + codeblock_t *block) \ + { \ + uint32_t offset = fetchdat & 0xff; \ + \ + if (offset & 0x80) \ + offset |= 0xffffff00; \ + \ + func(1, op_pc, offset, not ); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w(uint8_t opcode, \ + uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc, codeblock_t *block) \ + { \ + uint32_t offset = fetchdat & 0xffff; \ + \ + if (offset & 0x8000) \ + offset |= 0xffff0000; \ + \ + func(2, op_pc, offset, not ); \ + \ + return op_pc + 2; \ + } \ + static uint32_t rop##name##_l(uint8_t opcode, \ + uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc, codeblock_t *block) \ + { \ + uint32_t offset = fastreadl(cs + op_pc); \ + \ + func(4, op_pc, offset, not ); \ + \ + return op_pc + 4; \ + } -#define ropBRANCH(name, func, not) \ -static uint32_t rop ## name(uint8_t opcode, uint32_t fetchdat, \ - uint32_t op_32, uint32_t op_pc, \ - codeblock_t *block) \ -{ \ - uint32_t offset = fetchdat & 0xff; \ - \ - if (offset & 0x80) \ - offset |= 0xffffff00; \ - \ - func(1, op_pc, offset, not); \ - \ - return op_pc+1; \ -} \ -static uint32_t rop ## name ## _w(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t offset = fetchdat & 0xffff; \ - \ - if (offset & 0x8000) \ - offset |= 0xffff0000; \ - \ - func(2, op_pc, offset, not); \ - \ - return op_pc+2; \ -} \ -static uint32_t rop ## name ## _l(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t offset = fastreadl(cs + op_pc); \ - \ - func(4, op_pc, offset, not); \ - \ - return op_pc+4; \ -} - +// clang-format off ropBRANCH(JB, BRANCH_COND_B, 0) ropBRANCH(JNB, BRANCH_COND_B, 1) ropBRANCH(JE, BRANCH_COND_E, 0) @@ -268,3 +269,4 @@ ropBRANCH(JLE, BRANCH_COND_LE, 0) ropBRANCH(JNLE, BRANCH_COND_LE, 1) ropBRANCH(JBE, BRANCH_COND_BE, 0) ropBRANCH(JNBE, BRANCH_COND_BE, 1) +// clang-format on diff --git a/src/codegen/codegen_ops_logic.h b/src/codegen/codegen_ops_logic.h index 117b19d97..55b4e117d 100644 --- a/src/codegen/codegen_ops_logic.h +++ b/src/codegen/codegen_ops_logic.h @@ -1,564 +1,540 @@ -#define ROP_LOGIC(name, op, writeback) \ - static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \ - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \ - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \ - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_B_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_W_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_L_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } +#define ROP_LOGIC(name, op, writeback) \ + static uint32_t rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \ + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_B_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_W(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \ + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_W_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_L(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \ + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_L_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_B(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_B_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_W(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_W_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_L(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_L_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } ROP_LOGIC(AND, AND, 1) ROP_LOGIC(OR, OR, 1) ROP_LOGIC(XOR, XOR, 1) -static uint32_t ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_B(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_B(target_seg); + src_reg = 0; + } + + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + dst_reg = TEST_HOST_REG_B(dst_reg, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + return op_pc + 1; +} +static uint32_t +ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int src_reg, dst_reg; + + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_W(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_W(target_seg); + src_reg = 0; + } + + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + dst_reg = TEST_HOST_REG_W(dst_reg, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + return op_pc + 1; +} +static uint32_t +ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int src_reg, dst_reg; + + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_L(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_L(target_seg); + src_reg = 0; + } + + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + dst_reg = TEST_HOST_REG_L(dst_reg, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + return op_pc + 1; +} + +static uint32_t +ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + AND_HOST_REG_IMM(host_reg, (fetchdat & 0xff) | 0xffffff00); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + return op_pc + 1; +} +static uint32_t +ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + AND_HOST_REG_IMM(host_reg, (fetchdat & 0xffff) | 0xffff0000); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + return op_pc + 2; +} +static uint32_t +ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + fetchdat = fastreadl(cs + op_pc); + AND_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + return op_pc + 4; +} + +static uint32_t +ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + OR_HOST_REG_IMM(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + return op_pc + 1; +} +static uint32_t +ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + return op_pc + 2; +} +static uint32_t +ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + fetchdat = fastreadl(cs + op_pc); + OR_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + return op_pc + 4; +} + +static uint32_t +ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + return op_pc + 1; +} +static uint32_t +ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + return op_pc + 2; +} +static uint32_t +ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + fetchdat = fastreadl(cs + op_pc); + host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + return op_pc + 4; +} + +static uint32_t +ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + return op_pc + 1; +} +static uint32_t +ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + return op_pc + 2; +} +static uint32_t +ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + fetchdat = fastreadl(cs + op_pc); + XOR_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + return op_pc + 4; +} + +static uint32_t +ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + x86seg *target_seg; + int host_reg; + uint8_t imm; + + switch (fetchdat & 0x38) { + case 0x00: /*TEST b,#8*/ + if ((fetchdat & 0xc0) == 0xc0) { + host_reg = LOAD_REG_B(fetchdat & 7); + imm = (fetchdat >> 8) & 0xff; + } else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + imm = fastreadb(cs + op_pc + 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); MEM_LOAD_ADDR_EA_B(target_seg); - src_reg = 0; - } + host_reg = 0; + } + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + host_reg = TEST_HOST_REG_IMM(host_reg, imm); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + return op_pc + 2; - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - dst_reg = TEST_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + case 0x10: /*NOT b*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + host_reg = LOAD_REG_B(fetchdat & 7); + XOR_HOST_REG_IMM(host_reg, 0xff); + STORE_REG_B_RELEASE(host_reg); + return op_pc + 1; - return op_pc + 1; + case 0x18: /*NEG b*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + host_reg = LOAD_REG_B(fetchdat & 7); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, host_reg); + NEG_HOST_REG_B(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op1, 0); + STORE_REG_B_RELEASE(host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + return op_pc + 1; + } + + return 0; } -static uint32_t ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + x86seg *target_seg; + int host_reg; + uint16_t imm; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + switch (fetchdat & 0x38) { + case 0x00: /*TEST w,#*/ + if ((fetchdat & 0xc0) == 0xc0) { + host_reg = LOAD_REG_W(fetchdat & 7); + imm = (fetchdat >> 8) & 0xffff; + } else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + imm = fastreadw(cs + op_pc + 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); MEM_LOAD_ADDR_EA_W(target_seg); - src_reg = 0; - } + host_reg = 0; + } + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + host_reg = TEST_HOST_REG_IMM(host_reg, imm); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + return op_pc + 3; - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - dst_reg = TEST_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + case 0x10: /*NOT w*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + host_reg = LOAD_REG_W(fetchdat & 7); + XOR_HOST_REG_IMM(host_reg, 0xffff); + STORE_REG_W_RELEASE(host_reg); + return op_pc + 1; - return op_pc + 1; + case 0x18: /*NEG w*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + host_reg = LOAD_REG_W(fetchdat & 7); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, host_reg); + NEG_HOST_REG_W(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op1, 0); + STORE_REG_W_RELEASE(host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + return op_pc + 1; + } + + return 0; } -static uint32_t ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + x86seg *target_seg; + int host_reg; + uint32_t imm; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + switch (fetchdat & 0x38) { + case 0x00: /*TEST l,#*/ + if ((fetchdat & 0xc0) == 0xc0) { + host_reg = LOAD_REG_L(fetchdat & 7); + imm = fastreadl(cs + op_pc + 1); + } else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + imm = fastreadl(cs + op_pc + 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); MEM_LOAD_ADDR_EA_L(target_seg); - src_reg = 0; - } + host_reg = 0; + } + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + host_reg = TEST_HOST_REG_IMM(host_reg, imm); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + return op_pc + 5; - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - dst_reg = TEST_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + case 0x10: /*NOT l*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + host_reg = LOAD_REG_L(fetchdat & 7); + XOR_HOST_REG_IMM(host_reg, 0xffffffff); + STORE_REG_L_RELEASE(host_reg); + return op_pc + 1; - return op_pc + 1; -} - -static uint32_t ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - AND_HOST_REG_IMM(host_reg, (fetchdat & 0xff) | 0xffffff00); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - AND_HOST_REG_IMM(host_reg, (fetchdat & 0xffff) | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - AND_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - OR_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - OR_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 1; -} -static uint32_t ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 2; -} -static uint32_t ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 4; -} - -static uint32_t ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - XOR_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint8_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_B(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadb(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 2; - - case 0x10: /*NOT b*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_B(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xff); - STORE_REG_B_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG b*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - host_reg = LOAD_REG_B(fetchdat & 7); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_B(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_B_RELEASE(host_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} -static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint16_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST w,#*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xffff; - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadw(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 3; - - case 0x10: /*NOT w*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_W(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xffff); - STORE_REG_W_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG w*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - host_reg = LOAD_REG_W(fetchdat & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_W(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_W_RELEASE(host_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} -static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint32_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST l,#*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_L(fetchdat & 7); - imm = fastreadl(cs + op_pc + 1); - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadl(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 5; - - case 0x10: /*NOT l*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_L(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xffffffff); - STORE_REG_L_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG l*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - host_reg = LOAD_REG_L(fetchdat & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_L(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_L_RELEASE(host_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; + case 0x18: /*NEG l*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + host_reg = LOAD_REG_L(fetchdat & 7); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, host_reg); + NEG_HOST_REG_L(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op1, 0); + STORE_REG_L_RELEASE(host_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + return op_pc + 1; + } + + return 0; } diff --git a/src/codegen/codegen_ops_misc.h b/src/codegen/codegen_ops_misc.h index 9438da2d3..61854ab37 100644 --- a/src/codegen/codegen_ops_misc.h +++ b/src/codegen/codegen_ops_misc.h @@ -1,272 +1,263 @@ -static uint32_t ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - return op_pc; + return op_pc; } -static uint32_t ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - CLEAR_BITS((uintptr_t)&cpu_state.flags, D_FLAG); - return op_pc; + CLEAR_BITS((uintptr_t) &cpu_state.flags, D_FLAG); + return op_pc; } -static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - SET_BITS((uintptr_t)&cpu_state.flags, D_FLAG); - return op_pc; + SET_BITS((uintptr_t) &cpu_state.flags, D_FLAG); + return op_pc; } -static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; - CLEAR_BITS((uintptr_t)&cpu_state.flags, I_FLAG); + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; + CLEAR_BITS((uintptr_t) &cpu_state.flags, I_FLAG); #ifdef CHECK_INT - CLEAR_BITS((uintptr_t)&pic_pending, 0xffffffff); + CLEAR_BITS((uintptr_t) &pic_pending, 0xffffffff); #endif - return op_pc; + return op_pc; } -static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; - SET_BITS((uintptr_t)&cpu_state.flags, I_FLAG); - return op_pc; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; + SET_BITS((uintptr_t) &cpu_state.flags, I_FLAG); + return op_pc; } -static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int host_reg; + x86seg *target_seg = NULL; + int host_reg; - if ((fetchdat & 0x30) != 0x00) - return 0; + if ((fetchdat & 0x30) != 0x00) + return 0; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_B(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0xc0) == 0xc0) + host_reg = LOAD_REG_B(fetchdat & 7); + else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); - } + SAVE_EA(); + MEM_CHECK_WRITE(target_seg); + host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); + } - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_B(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - break; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - break; - } + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_B(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + break; + case 0x08: /*DEC*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_B(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + break; + } - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_B_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_B_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; - return op_pc + 1; + return op_pc + 1; } static uint32_t codegen_temp; -static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int host_reg; + x86seg *target_seg = NULL; + int host_reg; - if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) - return 0; - - if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_W(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0x30) != 0x00) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_W_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_W_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - - case 0x10: /*CALL*/ - STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, host_reg); - RELEASE_REG(host_reg); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(op_pc + 1); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); - - host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); - STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x20: /*JMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x30: /*PUSH*/ - if (!host_reg) - host_reg = LOAD_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); - return op_pc + 1; - } + if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) return 0; + + if ((fetchdat & 0x30) == 0x00) + CALL_FUNC((uintptr_t) flags_rebuild_c); + + if ((fetchdat & 0xc0) == 0xc0) + host_reg = LOAD_REG_W(fetchdat & 7); + else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + if ((fetchdat & 0x30) != 0x00) { + MEM_LOAD_ADDR_EA_W(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_W(target_seg); + host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); + } + } + + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_W(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_W_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; + return op_pc + 1; + case 0x08: /*DEC*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_W(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_W_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; + return op_pc + 1; + + case 0x10: /*CALL*/ + STORE_HOST_REG_ADDR_W((uintptr_t) &codegen_temp, host_reg); + RELEASE_REG(host_reg); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_IMM(op_pc + 1); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); + + host_reg = LOAD_VAR_W((uintptr_t) &codegen_temp); + STORE_HOST_REG_ADDR_W((uintptr_t) &cpu_state.pc, host_reg); + return -1; + + case 0x20: /*JMP*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg); + return -1; + + case 0x30: /*PUSH*/ + if (!host_reg) + host_reg = LOAD_HOST_REG(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); + return op_pc + 1; + } + return 0; } -static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int host_reg; + x86seg *target_seg = NULL; + int host_reg; - if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) - return 0; - - if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_L(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0x30) != 0x00) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_L(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_L_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_L_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - - case 0x10: /*CALL*/ - STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, host_reg); - RELEASE_REG(host_reg); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(op_pc + 1); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); - - host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x20: /*JMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x30: /*PUSH*/ - if (!host_reg) - host_reg = LOAD_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); - return op_pc + 1; - } + if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) return 0; + + if ((fetchdat & 0x30) == 0x00) + CALL_FUNC((uintptr_t) flags_rebuild_c); + + if ((fetchdat & 0xc0) == 0xc0) + host_reg = LOAD_REG_L(fetchdat & 7); + else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + if ((fetchdat & 0x30) != 0x00) { + MEM_LOAD_ADDR_EA_L(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_L(target_seg); + host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); + } + } + + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_L_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; + return op_pc + 1; + case 0x08: /*DEC*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_L_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; + return op_pc + 1; + + case 0x10: /*CALL*/ + STORE_HOST_REG_ADDR((uintptr_t) &codegen_temp, host_reg); + RELEASE_REG(host_reg); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_IMM(op_pc + 1); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); + + host_reg = LOAD_VAR_L((uintptr_t) &codegen_temp); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg); + return -1; + + case 0x20: /*JMP*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg); + return -1; + + case 0x30: /*PUSH*/ + if (!host_reg) + host_reg = LOAD_HOST_REG(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); + return op_pc + 1; + } + return 0; } diff --git a/src/codegen/codegen_ops_mmx.h b/src/codegen/codegen_ops_mmx.h index 4cdb080fb..edb5b0586 100644 --- a/src/codegen/codegen_ops_mmx.h +++ b/src/codegen/codegen_ops_mmx.h @@ -1,277 +1,267 @@ -static uint32_t ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg1, host_reg2 = 0; + int host_reg1, host_reg2 = 0; - MMX_ENTER(); + MMX_ENTER(); - LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2); + LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2); - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 7); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 7); - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - } + MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - MMX_ENTER(); + MMX_ENTER(); - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg1, host_reg2; + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg1, host_reg2; - LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2); - STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2); + STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); + CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); - STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2); - } + MEM_LOAD_ADDR_EA_Q(target_seg); + STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - MMX_ENTER(); + MMX_ENTER(); - host_reg = LOAD_MMX_D((fetchdat >> 3) & 7); + host_reg = LOAD_MMX_D((fetchdat >> 3) & 7); - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 3); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 3); - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - } + MEM_STORE_ADDR_EA_L(target_seg, host_reg); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - MMX_ENTER(); + MMX_ENTER(); - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_L(fetchdat & 7); - STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_L(fetchdat & 7); + STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); + CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - STORE_MMX_LQ((fetchdat >> 3) & 7, 0); - } + MEM_LOAD_ADDR_EA_L(target_seg); + STORE_MMX_LQ((fetchdat >> 3) & 7, 0); + } - return op_pc + 1; + return op_pc + 1; } #define MMX_OP(name, func) \ -static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ + static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ int src_reg1, src_reg2; \ int xmm_src, xmm_dst; \ \ MMX_ENTER(); \ \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ \ - CHECK_SEG_READ(target_seg); \ + CHECK_SEG_READ(target_seg); \ \ - MEM_LOAD_ADDR_EA_Q(target_seg); \ - src_reg1 = LOAD_Q_REG_1; \ - src_reg2 = LOAD_Q_REG_2; \ - xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ + MEM_LOAD_ADDR_EA_Q(target_seg); \ + src_reg1 = LOAD_Q_REG_1; \ + src_reg2 = LOAD_Q_REG_2; \ + xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ } \ xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \ - func(xmm_dst, xmm_src); \ + func(xmm_dst, xmm_src); \ STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \ \ return op_pc + 1; \ -} + } -MMX_OP(ropPAND, MMX_AND) +MMX_OP(ropPAND, MMX_AND) MMX_OP(ropPANDN, MMX_ANDN) -MMX_OP(ropPOR, MMX_OR) -MMX_OP(ropPXOR, MMX_XOR) +MMX_OP(ropPOR, MMX_OR) +MMX_OP(ropPXOR, MMX_XOR) -MMX_OP(ropPADDB, MMX_ADDB) -MMX_OP(ropPADDW, MMX_ADDW) -MMX_OP(ropPADDD, MMX_ADDD) -MMX_OP(ropPADDSB, MMX_ADDSB) -MMX_OP(ropPADDSW, MMX_ADDSW) -MMX_OP(ropPADDUSB, MMX_ADDUSB) -MMX_OP(ropPADDUSW, MMX_ADDUSW) +MMX_OP(ropPADDB, MMX_ADDB) +MMX_OP(ropPADDW, MMX_ADDW) +MMX_OP(ropPADDD, MMX_ADDD) +MMX_OP(ropPADDSB, MMX_ADDSB) +MMX_OP(ropPADDSW, MMX_ADDSW) +MMX_OP(ropPADDUSB, MMX_ADDUSB) +MMX_OP(ropPADDUSW, MMX_ADDUSW) -MMX_OP(ropPSUBB, MMX_SUBB) -MMX_OP(ropPSUBW, MMX_SUBW) -MMX_OP(ropPSUBD, MMX_SUBD) -MMX_OP(ropPSUBSB, MMX_SUBSB) -MMX_OP(ropPSUBSW, MMX_SUBSW) -MMX_OP(ropPSUBUSB, MMX_SUBUSB) -MMX_OP(ropPSUBUSW, MMX_SUBUSW) +MMX_OP(ropPSUBB, MMX_SUBB) +MMX_OP(ropPSUBW, MMX_SUBW) +MMX_OP(ropPSUBD, MMX_SUBD) +MMX_OP(ropPSUBSB, MMX_SUBSB) +MMX_OP(ropPSUBSW, MMX_SUBSW) +MMX_OP(ropPSUBUSB, MMX_SUBUSB) +MMX_OP(ropPSUBUSW, MMX_SUBUSW) MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW); MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD); MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ); -MMX_OP(ropPACKSSWB, MMX_PACKSSWB); -MMX_OP(ropPCMPGTB, MMX_PCMPGTB); -MMX_OP(ropPCMPGTW, MMX_PCMPGTW); -MMX_OP(ropPCMPGTD, MMX_PCMPGTD); -MMX_OP(ropPACKUSWB, MMX_PACKUSWB); +MMX_OP(ropPACKSSWB, MMX_PACKSSWB); +MMX_OP(ropPCMPGTB, MMX_PCMPGTB); +MMX_OP(ropPCMPGTW, MMX_PCMPGTW); +MMX_OP(ropPCMPGTD, MMX_PCMPGTD); +MMX_OP(ropPACKUSWB, MMX_PACKUSWB); MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW); MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD); MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ); -MMX_OP(ropPACKSSDW, MMX_PACKSSDW); +MMX_OP(ropPACKSSDW, MMX_PACKSSDW); -MMX_OP(ropPCMPEQB, MMX_PCMPEQB); -MMX_OP(ropPCMPEQW, MMX_PCMPEQW); -MMX_OP(ropPCMPEQD, MMX_PCMPEQD); +MMX_OP(ropPCMPEQB, MMX_PCMPEQB); +MMX_OP(ropPCMPEQW, MMX_PCMPEQW); +MMX_OP(ropPCMPEQD, MMX_PCMPEQD); -MMX_OP(ropPSRLW, MMX_PSRLW) -MMX_OP(ropPSRLD, MMX_PSRLD) -MMX_OP(ropPSRLQ, MMX_PSRLQ) -MMX_OP(ropPSRAW, MMX_PSRAW) -MMX_OP(ropPSRAD, MMX_PSRAD) -MMX_OP(ropPSLLW, MMX_PSLLW) -MMX_OP(ropPSLLD, MMX_PSLLD) -MMX_OP(ropPSLLQ, MMX_PSLLQ) +MMX_OP(ropPSRLW, MMX_PSRLW) +MMX_OP(ropPSRLD, MMX_PSRLD) +MMX_OP(ropPSRLQ, MMX_PSRLQ) +MMX_OP(ropPSRAW, MMX_PSRAW) +MMX_OP(ropPSRAD, MMX_PSRAD) +MMX_OP(ropPSLLW, MMX_PSLLW) +MMX_OP(ropPSLLD, MMX_PSLLD) +MMX_OP(ropPSLLQ, MMX_PSLLQ) -MMX_OP(ropPMULLW, MMX_PMULLW); -MMX_OP(ropPMULHW, MMX_PMULHW); -MMX_OP(ropPMADDWD, MMX_PMADDWD); +MMX_OP(ropPMULLW, MMX_PMULLW); +MMX_OP(ropPMULHW, MMX_PMULHW); +MMX_OP(ropPMADDWD, MMX_PMADDWD); -static uint32_t ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLW*/ - MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAW*/ - MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLW*/ - MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} -static uint32_t ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLD*/ - MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAD*/ - MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLD*/ - MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} -static uint32_t ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLQ*/ - MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAQ*/ - MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLQ*/ - MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} - -static uint32_t ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - codegen_mmx_entered = 0; + int xmm_dst; + if ((fetchdat & 0xc0) != 0xc0) return 0; + if ((fetchdat & 0x08) || !(fetchdat & 0x30)) + return 0; + + MMX_ENTER(); + + xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); + switch (fetchdat & 0x38) { + case 0x10: /*PSRLW*/ + MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x20: /*PSRAW*/ + MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x30: /*PSLLW*/ + MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + } + STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); + + return op_pc + 2; +} +static uint32_t +ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int xmm_dst; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + if ((fetchdat & 0x08) || !(fetchdat & 0x30)) + return 0; + + MMX_ENTER(); + + xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); + switch (fetchdat & 0x38) { + case 0x10: /*PSRLD*/ + MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x20: /*PSRAD*/ + MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x30: /*PSLLD*/ + MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + } + STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); + + return op_pc + 2; +} +static uint32_t +ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int xmm_dst; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + if ((fetchdat & 0x08) || !(fetchdat & 0x30)) + return 0; + + MMX_ENTER(); + + xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); + switch (fetchdat & 0x38) { + case 0x10: /*PSRLQ*/ + MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x20: /*PSRAQ*/ + MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x30: /*PSLLQ*/ + MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + } + STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); + + return op_pc + 2; +} + +static uint32_t +ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + codegen_mmx_entered = 0; + + return 0; } diff --git a/src/codegen/codegen_ops_mov.h b/src/codegen/codegen_ops_mov.h index df7a6a31b..04c4bf2bc 100644 --- a/src/codegen/codegen_ops_mov.h +++ b/src/codegen/codegen_ops_mov.h @@ -1,656 +1,625 @@ -static uint32_t ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_REG_B(opcode & 7, fetchdat & 0xff); + STORE_IMM_REG_B(opcode & 7, fetchdat & 0xff); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_REG_W(opcode & 7, fetchdat & 0xffff); + STORE_IMM_REG_W(opcode & 7, fetchdat & 0xffff); - return op_pc + 2; + return op_pc + 2; } -static uint32_t ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - fetchdat = fastreadl(cs + op_pc); + fetchdat = fastreadl(cs + op_pc); - STORE_IMM_REG_L(opcode & 7, fetchdat); + STORE_IMM_REG_L(opcode & 7, fetchdat); - return op_pc + 4; + return op_pc + 4; } - -static uint32_t ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_B((fetchdat >> 3) & 7); + int host_reg = LOAD_REG_B((fetchdat >> 3) & 7); - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 0); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 0); - MEM_STORE_ADDR_EA_B(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 1); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - host_reg = LOAD_REG_L((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 3); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - RELEASE_REG(host_reg); - - } - - return op_pc + 1; -} - -static uint32_t ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - STORE_REG_TARGET_B_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_L(fetchdat & 7); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_L(target_seg); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadb(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_B(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 2; -} -static uint32_t ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadw(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 3; -} -static uint32_t ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - uint32_t imm = fastreadl(cs + op_pc + 1); - - STORE_IMM_REG_L(fetchdat & 7, imm); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadl(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 5; -} - - -static uint32_t ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_B(op_ea_seg, addr); - STORE_REG_TARGET_B_RELEASE(0, REG_AL); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_W(op_ea_seg, addr); - STORE_REG_TARGET_W_RELEASE(0, REG_AX); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_L(op_ea_seg, addr); - STORE_REG_TARGET_L_RELEASE(0, REG_EAX); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -static uint32_t ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - int host_reg; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - host_reg = LOAD_REG_B(REG_AL); - - MEM_STORE_ADDR_IMM_B(op_ea_seg, addr, host_reg); + MEM_STORE_ADDR_EA_B(target_seg, host_reg); RELEASE_REG(host_reg); + } - return op_pc + ((op_32 & 0x200) ? 4 : 2); + return op_pc + 1; } -static uint32_t ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t addr; - int host_reg; + int host_reg = LOAD_REG_W((fetchdat >> 3) & 7); - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - host_reg = LOAD_REG_W(REG_AX); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 1); - MEM_STORE_ADDR_IMM_W(op_ea_seg, addr, host_reg); + MEM_STORE_ADDR_EA_W(target_seg, host_reg); RELEASE_REG(host_reg); + } - return op_pc + ((op_32 & 0x200) ? 4 : 2); + return op_pc + 1; } -static uint32_t ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) + +static uint32_t +ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t addr; - int host_reg; + int host_reg; - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); + host_reg = LOAD_REG_L((fetchdat >> 3) & 7); - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - host_reg = LOAD_REG_L(REG_EAX); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - MEM_STORE_ADDR_IMM_L(op_ea_seg, addr, host_reg); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 3); + + MEM_STORE_ADDR_EA_L(target_seg, host_reg); RELEASE_REG(host_reg); + } - return op_pc + ((op_32 & 0x200) ? 4 : 2); + return op_pc + 1; } -static uint32_t ropLEA_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int dest_reg = (fetchdat >> 3) & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - if ((fetchdat & 0xc0) == 0xc0) - return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + CHECK_SEG_READ(target_seg); - STORE_REG_TARGET_W_RELEASE(0, dest_reg); + MEM_LOAD_ADDR_EA_B(target_seg); + STORE_REG_TARGET_B_RELEASE(0, (fetchdat >> 3) & 7); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropLEA_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int dest_reg = (fetchdat >> 3) & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_W(fetchdat & 7); + STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - if ((fetchdat & 0xc0) == 0xc0) - return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + CHECK_SEG_READ(target_seg); - STORE_REG_TARGET_L_RELEASE(0, dest_reg); + MEM_LOAD_ADDR_EA_W(target_seg); + STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); + } - return op_pc + 1; + return op_pc + 1; +} +static uint32_t +ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_L(fetchdat & 7); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_L(target_seg); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; } -static uint32_t ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = ZERO_EXTEND_W_B(host_reg); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } + if ((fetchdat & 0xc0) == 0xc0) { + STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + uint32_t imm = fastreadb(cs + op_pc + 1); + int host_reg = LOAD_REG_IMM(imm); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + CHECK_SEG_WRITE(target_seg); + + MEM_STORE_ADDR_EA_B(target_seg, host_reg); + RELEASE_REG(host_reg); + } + + return op_pc + 2; +} +static uint32_t +ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + uint32_t imm = fastreadw(cs + op_pc + 1); + int host_reg = LOAD_REG_IMM(imm); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + CHECK_SEG_WRITE(target_seg); + + MEM_STORE_ADDR_EA_W(target_seg, host_reg); + RELEASE_REG(host_reg); + } + + return op_pc + 3; +} +static uint32_t +ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + uint32_t imm = fastreadl(cs + op_pc + 1); + + STORE_IMM_REG_L(fetchdat & 7, imm); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + uint32_t imm = fastreadl(cs + op_pc + 1); + int host_reg = LOAD_REG_IMM(imm); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + CHECK_SEG_WRITE(target_seg); + + MEM_STORE_ADDR_EA_L(target_seg, host_reg); + RELEASE_REG(host_reg); + } + + return op_pc + 5; +} + +static uint32_t +ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_READ(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + MEM_LOAD_ADDR_IMM_B(op_ea_seg, addr); + STORE_REG_TARGET_B_RELEASE(0, REG_AL); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +static uint32_t +ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_READ(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + MEM_LOAD_ADDR_IMM_W(op_ea_seg, addr); + STORE_REG_TARGET_W_RELEASE(0, REG_AX); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +static uint32_t +ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_READ(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + MEM_LOAD_ADDR_IMM_L(op_ea_seg, addr); + STORE_REG_TARGET_L_RELEASE(0, REG_EAX); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} + +static uint32_t +ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + int host_reg; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_WRITE(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + host_reg = LOAD_REG_B(REG_AL); + + MEM_STORE_ADDR_IMM_B(op_ea_seg, addr, host_reg); + RELEASE_REG(host_reg); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +static uint32_t +ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + int host_reg; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_WRITE(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + host_reg = LOAD_REG_W(REG_AX); + + MEM_STORE_ADDR_IMM_W(op_ea_seg, addr, host_reg); + RELEASE_REG(host_reg); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +static uint32_t +ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + int host_reg; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_WRITE(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + host_reg = LOAD_REG_L(REG_EAX); + + MEM_STORE_ADDR_IMM_L(op_ea_seg, addr, host_reg); + RELEASE_REG(host_reg); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} + +static uint32_t +ropLEA_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + return 0; + + FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_REG_TARGET_W_RELEASE(0, dest_reg); + + return op_pc + 1; +} +static uint32_t +ropLEA_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + return 0; + + FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_REG_TARGET_L_RELEASE(0, dest_reg); + + return op_pc + 1; +} + +static uint32_t +ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + host_reg = ZERO_EXTEND_W_B(host_reg); + STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_B(target_seg); + ZERO_EXTEND_W_B(0); + STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} +static uint32_t +ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + host_reg = ZERO_EXTEND_L_B(host_reg); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_B(target_seg); + ZERO_EXTEND_L_B(0); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} +static uint32_t +ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_W(fetchdat & 7); + host_reg = ZERO_EXTEND_L_W(host_reg); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_W(target_seg); + ZERO_EXTEND_L_W(0); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} + +static uint32_t +ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + host_reg = SIGN_EXTEND_W_B(host_reg); + STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_B(target_seg); + SIGN_EXTEND_W_B(0); + STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} +static uint32_t +ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + host_reg = SIGN_EXTEND_L_B(host_reg); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_B(target_seg); + SIGN_EXTEND_L_B(0); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} +static uint32_t +ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_W(fetchdat & 7); + host_reg = SIGN_EXTEND_L_W(host_reg); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_W(target_seg); + SIGN_EXTEND_L_W(0); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} + +static uint32_t +ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg; + + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + host_reg = LOAD_VAR_WL((uintptr_t) &ES); + break; + case 0x08: /*CS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &CS); + break; + case 0x18: /*DS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &DS); + break; + case 0x10: /*SS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &SS); + break; + case 0x20: /*FS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &FS); + break; + case 0x28: /*GS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &GS); + break; + default: + return 0; + } + + if ((fetchdat & 0xc0) == 0xc0) { + if (op_32 & 0x100) + STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 1); - MEM_LOAD_ADDR_EA_B(target_seg); - ZERO_EXTEND_W_B(0); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } + MEM_STORE_ADDR_EA_W(target_seg, host_reg); + RELEASE_REG(host_reg); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = ZERO_EXTEND_L_B(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + case 0x18: /*DS*/ + case 0x20: /*FS*/ + case 0x28: /*GS*/ + break; + case 0x10: /*SS*/ + default: + return 0; + } - CHECK_SEG_READ(target_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - ZERO_EXTEND_L_B(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } + if ((fetchdat & 0xc0) == 0xc0) + host_reg = LOAD_REG_W(fetchdat & 7); + else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - return op_pc + 1; -} -static uint32_t ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - host_reg = ZERO_EXTEND_L_W(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_W(target_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + host_reg = 0; + } - CHECK_SEG_READ(target_seg); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + LOAD_SEG(host_reg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + LOAD_SEG(host_reg, &cpu_state.seg_ds); + break; + case 0x20: /*FS*/ + LOAD_SEG(host_reg, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + LOAD_SEG(host_reg, &cpu_state.seg_gs); + break; + } - MEM_LOAD_ADDR_EA_W(target_seg); - ZERO_EXTEND_L_W(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = SIGN_EXTEND_W_B(host_reg); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - SIGN_EXTEND_W_B(0); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = SIGN_EXTEND_L_B(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - SIGN_EXTEND_L_B(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - host_reg = SIGN_EXTEND_L_W(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - SIGN_EXTEND_L_W(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - host_reg = LOAD_VAR_WL((uintptr_t)&ES); - break; - case 0x08: /*CS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&CS); - break; - case 0x18: /*DS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&DS); - break; - case 0x10: /*SS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&SS); - break; - case 0x20: /*FS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&FS); - break; - case 0x28: /*GS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&GS); - break; - default: - return 0; - } - - if ((fetchdat & 0xc0) == 0xc0) - { - if (op_32 & 0x100) - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - else - STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 1); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - case 0x18: /*DS*/ - case 0x20: /*FS*/ - case 0x28: /*GS*/ - break; - case 0x10: /*SS*/ - default: - return 0; - } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_W(fetchdat & 7); - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); - - host_reg = 0; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - LOAD_SEG(host_reg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - LOAD_SEG(host_reg, &cpu_state.seg_ds); - break; - case 0x20: /*FS*/ - LOAD_SEG(host_reg, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - LOAD_SEG(host_reg, &cpu_state.seg_gs); - break; - } - - return op_pc + 1; -} - -#define ropLseg(seg, rseg) \ -static uint32_t ropL ## seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - SAVE_EA(); \ - \ - if (op_32 & 0x100) \ - { \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, 0); \ - LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \ - } \ - else \ - { \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, 0); \ - LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \ - } \ - LOAD_SEG(0, &rseg); \ - if (op_32 & 0x100) \ - { \ - \ - int host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); \ - STORE_REG_TARGET_L_RELEASE(host_reg, dest_reg); \ - } \ - else \ - { \ - int host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); \ - STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \ - } \ - \ - if (&rseg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \ - return op_pc + 1; \ -} +#define ropLseg(seg, rseg) \ + static uint32_t ropL##seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + SAVE_EA(); \ + \ + if (op_32 & 0x100) { \ + MEM_LOAD_ADDR_EA_L(target_seg); \ + STORE_HOST_REG_ADDR((uintptr_t) &codegen_temp, 0); \ + LOAD_EA(); \ + MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \ + } else { \ + MEM_LOAD_ADDR_EA_W(target_seg); \ + STORE_HOST_REG_ADDR_W((uintptr_t) &codegen_temp, 0); \ + LOAD_EA(); \ + MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \ + } \ + LOAD_SEG(0, &rseg); \ + if (op_32 & 0x100) { \ + \ + int host_reg = LOAD_VAR_L((uintptr_t) &codegen_temp); \ + STORE_REG_TARGET_L_RELEASE(host_reg, dest_reg); \ + } else { \ + int host_reg = LOAD_VAR_W((uintptr_t) &codegen_temp); \ + STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \ + } \ + \ + if (&rseg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \ + return op_pc + 1; \ + } +// clang-format off ropLseg(DS, cpu_state.seg_ds) ropLseg(ES, cpu_state.seg_es) ropLseg(FS, cpu_state.seg_fs) ropLseg(GS, cpu_state.seg_gs) ropLseg(SS, cpu_state.seg_ss) +// clang-format on diff --git a/src/codegen/codegen_ops_shift.h b/src/codegen/codegen_ops_shift.h index 57a828232..d750bfcad 100644 --- a/src/codegen/codegen_ops_shift.h +++ b/src/codegen/codegen_ops_shift.h @@ -1,125 +1,129 @@ -#define SHIFT(size, size2, res_store, immediate) \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - reg = LOAD_REG_ ## size(fetchdat & 7); \ - if (immediate) count = (fetchdat >> 8) & 0x1f; \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_ ## size(target_seg); \ - reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \ - if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count); \ - \ - res_store((uintptr_t)&cpu_state.flags_op1, reg); \ - \ - switch (fetchdat & 0x38) \ - { \ - case 0x20: case 0x30: /*SHL*/ \ - SHL_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \ - break; \ - \ - case 0x28: /*SHR*/ \ - SHR_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \ - break; \ - \ - case 0x38: /*SAR*/ \ - SAR_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \ - break; \ - } \ - \ - res_store((uintptr_t)&cpu_state.flags_res, reg); \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_ ## size ## _RELEASE(reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_ ## size ## _NO_ABRT(target_seg, reg); \ - } +#define SHIFT(size, size2, res_store, immediate) \ + if ((fetchdat & 0xc0) == 0xc0) { \ + reg = LOAD_REG_##size(fetchdat & 7); \ + if (immediate) \ + count = (fetchdat >> 8) & 0x1f; \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_##size(target_seg); \ + reg = MEM_LOAD_ADDR_EA_##size##_NO_ABRT(target_seg); \ + if (immediate) \ + count = fastreadb(cs + op_pc + 1) & 0x1f; \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, count); \ + \ + res_store((uintptr_t) &cpu_state.flags_op1, reg); \ + \ + switch (fetchdat & 0x38) { \ + case 0x20: \ + case 0x30: /*SHL*/ \ + SHL_##size##_IMM(reg, count); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SHL##size2); \ + break; \ + \ + case 0x28: /*SHR*/ \ + SHR_##size##_IMM(reg, count); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SHR##size2); \ + break; \ + \ + case 0x38: /*SAR*/ \ + SAR_##size##_IMM(reg, count); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SAR##size2); \ + break; \ + } \ + \ + res_store((uintptr_t) &cpu_state.flags_res, reg); \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_##size##_RELEASE(reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_##size##_NO_ABRT(target_seg, reg); \ + } -static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count; - int reg; + x86seg *target_seg = NULL; + int count; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1); + SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1); - return op_pc + 2; + return op_pc + 2; } -static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count; - int reg; + x86seg *target_seg = NULL; + int count; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1); + SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1); - return op_pc + 2; + return op_pc + 2; } -static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count; - int reg; + x86seg *target_seg = NULL; + int count; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(L, 32, STORE_HOST_REG_ADDR, 1); + SHIFT(L, 32, STORE_HOST_REG_ADDR, 1); - return op_pc + 2; + return op_pc + 2; } -static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count = 1; - int reg; + x86seg *target_seg = NULL; + int count = 1; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0); + SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count = 1; - int reg; + x86seg *target_seg = NULL; + int count = 1; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0); + SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count = 1; - int reg; + x86seg *target_seg = NULL; + int count = 1; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(L, 32, STORE_HOST_REG_ADDR, 0); + SHIFT(L, 32, STORE_HOST_REG_ADDR, 0); - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen/codegen_ops_stack.h b/src/codegen/codegen_ops_stack.h index d2fc53aad..265369771 100644 --- a/src/codegen/codegen_ops_stack.h +++ b/src/codegen/codegen_ops_stack.h @@ -1,238 +1,254 @@ -static uint32_t ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_W(opcode & 7); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_W(opcode & 7); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); - return op_pc; + return op_pc; } -static uint32_t ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_L(opcode & 7); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_L(opcode & 7); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); - return op_pc; + return op_pc; } -static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t imm = fetchdat & 0xffff; - int host_reg; + uint16_t imm = fetchdat & 0xffff; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_IMM(imm); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); - return op_pc+2; + return op_pc + 2; } -static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t imm = fastreadl(cs + op_pc); - int host_reg; + uint32_t imm = fastreadl(cs + op_pc); + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_IMM(imm); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); - return op_pc+4; + return op_pc + 4; } -static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t imm = fetchdat & 0xff; - int host_reg; + uint16_t imm = fetchdat & 0xff; + int host_reg; - if (imm & 0x80) - imm |= 0xff00; + if (imm & 0x80) + imm |= 0xff00; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_IMM(imm); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); - return op_pc+1; + return op_pc + 1; } -static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t imm = fetchdat & 0xff; - int host_reg; + uint32_t imm = fetchdat & 0xff; + int host_reg; - if (imm & 0x80) - imm |= 0xffffff00; + if (imm & 0x80) + imm |= 0xffffff00; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_IMM(imm); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); - return op_pc+1; + return op_pc + 1; } -static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); - SP_MODIFY(2); - STORE_REG_TARGET_W_RELEASE(0, opcode & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); + SP_MODIFY(2); + STORE_REG_TARGET_W_RELEASE(0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); - SP_MODIFY(4); - STORE_REG_TARGET_L_RELEASE(0, opcode & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); + SP_MODIFY(4); + STORE_REG_TARGET_L_RELEASE(0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0); + SP_MODIFY(2); - return -1; + return -1; } -static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0); + SP_MODIFY(4); - return -1; + return -1; } -static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t offset = fetchdat & 0xffff; + uint16_t offset = fetchdat & 0xffff; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(2+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0); + SP_MODIFY(2 + offset); - return -1; + return -1; } -static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t offset = fetchdat & 0xffff; + uint16_t offset = fetchdat & 0xffff; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(4+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0); + SP_MODIFY(4 + offset); - return -1; + return -1; } -static uint32_t ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t offset = fetchdat & 0xffff; - int host_reg; + uint16_t offset = fetchdat & 0xffff; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(op_pc+2); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_IMM(op_pc + 2); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, (op_pc + 2 + offset) & 0xffff); - return -1; + return -1; } -static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fastreadl(cs + op_pc); - int host_reg; + uint32_t offset = fastreadl(cs + op_pc); + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(op_pc+4); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_IMM(op_pc + 4); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 4 + offset); - return -1; + return -1; } -static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_EBP_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); - host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/ - ADD_HOST_REG_IMM_W(host_reg, 2); - STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP); - STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_EBP_TO_EA(0); + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); + host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/ + ADD_HOST_REG_IMM_W(host_reg, 2); + STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP); + STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/ - return op_pc; + return op_pc; } -static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_EBP_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); - host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/ - ADD_HOST_REG_IMM(host_reg, 4); - STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP); - STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_EBP_TO_EA(0); + MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); + host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/ + ADD_HOST_REG_IMM(host_reg, 4); + STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP); + STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/ - return op_pc; + return op_pc; } -#define ROP_PUSH_SEG(seg) \ -static uint32_t ropPUSH_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-2); \ - host_reg = LOAD_VAR_W((uintptr_t)&seg); \ - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \ - SP_MODIFY(-2); \ - \ - return op_pc; \ -} \ -static uint32_t ropPUSH_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-4); \ - host_reg = LOAD_VAR_W((uintptr_t)&seg); \ - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \ - SP_MODIFY(-4); \ - \ - return op_pc; \ -} +#define ROP_PUSH_SEG(seg) \ + static uint32_t ropPUSH_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int host_reg; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(-2); \ + host_reg = LOAD_VAR_W((uintptr_t) &seg); \ + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \ + SP_MODIFY(-2); \ + \ + return op_pc; \ + } \ + static uint32_t ropPUSH_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int host_reg; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(-4); \ + host_reg = LOAD_VAR_W((uintptr_t) &seg); \ + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \ + SP_MODIFY(-4); \ + \ + return op_pc; \ + } ROP_PUSH_SEG(CS) ROP_PUSH_SEG(DS) @@ -241,27 +257,27 @@ ROP_PUSH_SEG(FS) ROP_PUSH_SEG(GS) ROP_PUSH_SEG(SS) -#define ROP_POP_SEG(seg, rseg) \ -static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(2); \ - \ - return op_pc; \ -} \ -static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(4); \ - \ - return op_pc; \ -} +#define ROP_POP_SEG(seg, rseg) \ + static uint32_t ropPOP_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(0); \ + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ + LOAD_SEG(0, &rseg); \ + SP_MODIFY(2); \ + \ + return op_pc; \ + } \ + static uint32_t ropPOP_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(0); \ + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ + LOAD_SEG(0, &rseg); \ + SP_MODIFY(4); \ + \ + return op_pc; \ + } ROP_POP_SEG(DS, cpu_state.seg_ds) ROP_POP_SEG(ES, cpu_state.seg_es) diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index 9184b4bff..00518d9ba 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -4,4519 +4,4148 @@ #include #define HOST_REG_XMM_START 0 -#define HOST_REG_XMM_END 7 +#define HOST_REG_XMM_END 7 -#define IS_32_ADDR(x) !(((uintptr_t)x) & 0xffffffff00000000) +#define IS_32_ADDR(x) !(((uintptr_t) x) & 0xffffffff00000000) -static inline int find_host_xmm_reg() +static __inline int +find_host_xmm_reg(void) { - int c; - for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) - { - if (host_reg_xmm_mapping[c] == -1) - break; - } + int c; + for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) { + if (host_reg_xmm_mapping[c] == -1) + break; + } - if (c == HOST_REG_XMM_END) - fatal("Out of host XMM regs!\n"); - return c; + if (c == HOST_REG_XMM_END) + fatal("Out of host XMM regs!\n"); + return c; } -static inline void call(codeblock_t *block, uintptr_t func) +static __inline void +call(codeblock_t *block, uintptr_t func) { - intptr_t diff = (intptr_t)(func - (uintptr_t)&block->data[block_pos + 5]); + intptr_t diff = (intptr_t) (func - (uintptr_t) &block->data[block_pos + 5]); - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; + codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; + codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - if (diff >= -0x80000000LL && diff < 0x7fffffffLL) - { - addbyte(0xE8); /*CALL*/ - addlong((uint32_t)diff); - } - else - { - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); - } + if (diff >= -0x80000000LL && diff < 0x7fffffffLL) { + addbyte(0xE8); /*CALL*/ + addlong((uint32_t) diff); + } else { + addbyte(0x48); /*MOV RAX, func*/ + addbyte(0xb8); + addquad(func); + addbyte(0xff); /*CALL RAX*/ + addbyte(0xd0); + } } -static inline void call_long(uintptr_t func) +static __inline void +call_long(uintptr_t func) { - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; + codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; + codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); + addbyte(0x48); /*MOV RAX, func*/ + addbyte(0xb8); + addquad(func); + addbyte(0xff); /*CALL RAX*/ + addbyte(0xd0); } -static inline void load_param_1_32(codeblock_t *block, uint32_t param) +static __inline void +load_param_1_32(codeblock_t *block, uint32_t param) { #if _WIN64 - addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ + addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ #else - addbyte(0xbf); /*MOVL $fetchdat,%edi*/ + addbyte(0xbf); /*MOVL $fetchdat,%edi*/ #endif - addlong(param); + addlong(param); } -static inline void load_param_1_reg_32(int reg) +static __inline void +load_param_1_reg_32(int reg) { #if _WIN64 - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc0 | REG_ECX | (reg << 3)); + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc0 | REG_ECX | (reg << 3)); #else - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc0 | REG_EDI | (reg << 3)); + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV EDI, EAX*/ + addbyte(0xc0 | REG_EDI | (reg << 3)); #endif } #if 0 -static inline void load_param_1_64(codeblock_t *block, uint64_t param) +static __inline void load_param_1_64(codeblock_t *block, uint64_t param) { addbyte(0x48); -#if _WIN64 +# if _WIN64 addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ -#else +# else addbyte(0xbf); /*MOVL $fetchdat,%edi*/ -#endif +# endif addquad(param); } #endif -static inline void load_param_2_32(codeblock_t *block, uint32_t param) +static __inline void +load_param_2_32(codeblock_t *block, uint32_t param) { #if _WIN64 - addbyte(0xba); /*MOVL $fetchdat,%edx*/ + addbyte(0xba); /*MOVL $fetchdat,%edx*/ #else - addbyte(0xbe); /*MOVL $fetchdat,%esi*/ + addbyte(0xbe); /*MOVL $fetchdat,%esi*/ #endif - addlong(param); + addlong(param); } -static inline void load_param_2_reg_32(int reg) +static __inline void +load_param_2_reg_32(int reg) { #if _WIN64 - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV EDX, EAX*/ + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV EDX, EAX*/ + addbyte(0xc0 | REG_EDX | (reg << 3)); +#else + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV ESI, EAX*/ + addbyte(0xc0 | REG_ESI | (reg << 3)); +#endif +} +static __inline void +load_param_2_64(codeblock_t *block, uint64_t param) +{ + addbyte(0x48); +#if _WIN64 + addbyte(0xba); /*MOVL $fetchdat,%edx*/ +#else + addbyte(0xbe); /*MOVL $fetchdat,%esi*/ +#endif + addquad(param); +} +static __inline void +load_param_2_reg_64(int reg) +{ + if (reg & 8) { +#if _WIN64 + addbyte(0x4c); /*MOVL EDX,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); +#else + addbyte(0x4c); /*MOVL ESI,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_ESI | ((reg & 7) << 3)); +#endif + } else { +#if _WIN64 + addbyte(0x48); /*MOVL EDX,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); +#else + addbyte(0x48); /*MOVL ESI,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_ESI | ((reg & 7) << 3)); +#endif + } +} + +static __inline void +load_param_3_reg_32(int reg) +{ + if (reg & 8) { +#if _WIN64 + addbyte(0x45); /*MOVL R8,reg*/ + addbyte(0x89); + addbyte(0xc0 | ((reg & 7) << 3)); +#else + addbyte(0x44); /*MOV EDX, reg*/ + addbyte(0x89); addbyte(0xc0 | REG_EDX | (reg << 3)); -#else - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV ESI, EAX*/ - addbyte(0xc0 | REG_ESI | (reg << 3)); #endif -} -static inline void load_param_2_64(codeblock_t *block, uint64_t param) -{ - addbyte(0x48); + } else { #if _WIN64 - addbyte(0xba); /*MOVL $fetchdat,%edx*/ + addbyte(0x41); /*MOVL R8,reg*/ + addbyte(0x89); + addbyte(0xc0 | ((reg & 7) << 3)); #else - addbyte(0xbe); /*MOVL $fetchdat,%esi*/ + addbyte(0x90); + addbyte(0x89); /*MOV EDX, reg*/ + addbyte(0xc0 | REG_EDX | (reg << 3)); #endif - addquad(param); + } } -static inline void load_param_2_reg_64(int reg) +static __inline void +load_param_3_reg_64(int reg) { - if (reg & 8) - { + if (reg & 8) { #if _WIN64 - addbyte(0x4c); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); + addbyte(0x4d); /*MOVL R8,reg*/ + addbyte(0x89); + addbyte(0xc0 | ((reg & 7) << 3)); #else - addbyte(0x4c); /*MOVL ESI,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_ESI | ((reg & 7) << 3)); + addbyte(0x4c); /*MOVL EDX,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); #endif - } - else - { + } else { #if _WIN64 - addbyte(0x48); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); + addbyte(0x49); /*MOVL R8,reg*/ + addbyte(0x89); + addbyte(0xc0 | ((reg & 7) << 3)); #else - addbyte(0x48); /*MOVL ESI,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_ESI | ((reg & 7) << 3)); + addbyte(0x48); /*MOVL EDX,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); #endif + } +} + +static __inline void +CALL_FUNC(uintptr_t func) +{ + codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; + codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; + + addbyte(0x48); /*MOV RAX, func*/ + addbyte(0xb8); + addquad(func); + addbyte(0xff); /*CALL RAX*/ + addbyte(0xd0); +} + +static __inline void +RELEASE_REG(int host_reg) +{ +} + +static __inline int +LOAD_REG_B(int reg) +{ + int host_reg = reg & 3; + + if (!codegen_reg_loaded[reg & 3]) { + addbyte(0x44); /*MOVZX W[reg],host_reg*/ + addbyte(0x8b); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[host_reg & 3].b)); + } + + codegen_reg_loaded[reg & 3] = 1; + + if (reg & 4) + return host_reg | 0x18; + + return host_reg | 8; +} +static __inline int +LOAD_REG_W(int reg) +{ + int host_reg = reg; + + if (!codegen_reg_loaded[reg & 7]) { + addbyte(0x44); /*MOVZX W[reg],host_reg*/ + addbyte(0x8b); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[reg & 7].w)); + } + + codegen_reg_loaded[reg & 7] = 1; + + return host_reg | 8; +} +static __inline int +LOAD_REG_L(int reg) +{ + int host_reg = reg; + + if (!codegen_reg_loaded[reg & 7]) { + addbyte(0x44); /*MOVZX W[reg],host_reg*/ + addbyte(0x8b); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[reg & 7].l)); + } + + codegen_reg_loaded[reg & 7] = 1; + + return host_reg | 8; +} + +static __inline int +LOAD_REG_IMM(uint32_t imm) +{ + int host_reg = REG_EBX; + + addbyte(0xb8 | REG_EBX); /*MOVL EBX, imm*/ + addlong(imm); + + return host_reg; +} + +static __inline void +STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) +{ + int dest_reg = LOAD_REG_L(guest_reg & 3) & 7; + + if (guest_reg & 4) { + if (host_reg & 8) { + addbyte(0x66); /*MOV AX, host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 3) << 3)); + } else if (host_reg & 3) { + addbyte(0x66); /*MOV AX, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 3) << 3)); } -} - -static inline void load_param_3_reg_32(int reg) -{ - if (reg & 8) - { -#if _WIN64 - addbyte(0x45); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x44); /*MOV EDX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | (reg << 3)); -#endif + if (host_reg & 0x10) { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } else { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(0x08); } - else - { -#if _WIN64 - addbyte(0x41); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x90); - addbyte(0x89); /*MOV EDX, reg*/ - addbyte(0xc0 | REG_EDX | (reg << 3)); -#endif - } -} -static inline void load_param_3_reg_64(int reg) -{ - if (reg & 8) - { -#if _WIN64 - addbyte(0x4d); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x4c); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); -#endif - } - else - { -#if _WIN64 - addbyte(0x49); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x48); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); -#endif - } -} - -static inline void CALL_FUNC(uintptr_t func) -{ - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); -} - -static inline void RELEASE_REG(int host_reg) -{ -} - -static inline int LOAD_REG_B(int reg) -{ - int host_reg = reg & 3; - - if (!codegen_reg_loaded[reg & 3]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[host_reg & 3].b)); - } - - codegen_reg_loaded[reg & 3] = 1; - - if (reg & 4) - return host_reg | 0x18; - - return host_reg | 8; -} -static inline int LOAD_REG_W(int reg) -{ - int host_reg = reg; - - if (!codegen_reg_loaded[reg & 7]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].w)); - } - - codegen_reg_loaded[reg & 7] = 1; - - return host_reg | 8; -} -static inline int LOAD_REG_L(int reg) -{ - int host_reg = reg; - - if (!codegen_reg_loaded[reg & 7]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].l)); - } - - codegen_reg_loaded[reg & 7] = 1; - - return host_reg | 8; -} - -static inline int LOAD_REG_IMM(uint32_t imm) -{ - int host_reg = REG_EBX; - - addbyte(0xb8 | REG_EBX); /*MOVL EBX, imm*/ - addlong(imm); - - return host_reg; -} - -static inline void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) -{ - int dest_reg = LOAD_REG_L(guest_reg & 3) & 7; - - if (guest_reg & 4) - { - if (host_reg & 8) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - } - else if (host_reg & 3) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - } - if (host_reg & 0x10) - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - else - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(0x08); - } - addbyte(0x66); /*AND dest_reg, 0x00ff*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | dest_reg); - addword(0x00ff); - addbyte(0x66); /*OR dest_reg, AX*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | dest_reg); - addbyte(0x66); /*MOVW regs[guest_reg].w, dest_reg*/ + addbyte(0x66); /*AND dest_reg, 0x00ff*/ + addbyte(0x41); + addbyte(0x81); + addbyte(0xe0 | dest_reg); + addword(0x00ff); + addbyte(0x66); /*OR dest_reg, AX*/ + addbyte(0x41); + addbyte(0x09); + addbyte(0xc0 | dest_reg); + addbyte(0x66); /*MOVW regs[guest_reg].w, dest_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | (dest_reg << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 3].w)); + } else { + if (host_reg & 8) { + if (host_reg & 0x10) { + addbyte(0x66); /*MOV AX, host_reg*/ addbyte(0x44); addbyte(0x89); - addbyte(0x45 | (dest_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].w)); - } - else - { - if (host_reg & 8) - { - if (host_reg & 0x10) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - addbyte(0x88); /*MOV AL, AH*/ - addbyte(0xe0); - addbyte(0x41); /*MOV dest_reg, AL*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7)); - addbyte(0x88); /*MOVB regs[reg].b, AH*/ - addbyte(0x65); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - else - { - addbyte(0x45); /*MOVB dest_reg, host_reg*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); - addbyte(0x44); /*MOVB regs[guest_reg].b, host_reg*/ - addbyte(0x88); - addbyte(0x45 | ((host_reg & 3) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - } - else - { - if (host_reg & 0x10) - { - addbyte(0xc1); /*SHR host_reg, 8*/ - addbyte(0xe8 | (host_reg & 7)); - addbyte(8); - } - addbyte(0x41); /*MOVB dest_reg, host_reg*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); - addbyte(0x88); /*MOVB regs[guest_reg].b, host_reg*/ - addbyte(0x45 | ((host_reg & 3) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - } -} -static inline void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) -{ - int dest_reg = LOAD_REG_L(guest_reg & 7) & 7; - - if (host_reg & 8) - { - addbyte(0x66); /*MOVW guest_reg, host_reg*/ - addbyte(0x45); - addbyte(0x89); - addbyte(0xc0 | dest_reg | ((host_reg & 7) << 3)); - addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].w)); - } - else - { - addbyte(0x66); /*MOVW guest_reg, host_reg*/ - addbyte(0x41); - addbyte(0x89); - addbyte(0xc0 | dest_reg | (host_reg << 3)); - addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].w)); - } -} -static inline void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) -{ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL guest_reg, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | guest_reg | (host_reg << 3)); - addbyte(0x44); /*MOVL regs[guest_reg].l, host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].l)); - } - else - { - addbyte(0x41); /*MOVL guest_reg, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | guest_reg | (host_reg << 3)); - addbyte(0x89); /*MOVL regs[guest_reg].l, host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].l)); - } -} - -static inline void STORE_REG_B_RELEASE(int host_reg) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*MOVW [reg],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].w)); - } - else - { - addbyte(0x44); /*MOVB [reg],host_reg*/ + addbyte(0xc0 | ((host_reg & 3) << 3)); + addbyte(0x88); /*MOV AL, AH*/ + addbyte(0xe0); + addbyte(0x41); /*MOV dest_reg, AL*/ addbyte(0x88); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].b)); + addbyte(0xc0 | (dest_reg & 7)); + addbyte(0x88); /*MOVB regs[reg].b, AH*/ + addbyte(0x65); + addbyte(cpu_state_offset(regs[guest_reg & 3].b)); + } else { + addbyte(0x45); /*MOVB dest_reg, host_reg*/ + addbyte(0x88); + addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); + addbyte(0x44); /*MOVB regs[guest_reg].b, host_reg*/ + addbyte(0x88); + addbyte(0x45 | ((host_reg & 3) << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 3].b)); + } + } else { + if (host_reg & 0x10) { + addbyte(0xc1); /*SHR host_reg, 8*/ + addbyte(0xe8 | (host_reg & 7)); + addbyte(8); + } + addbyte(0x41); /*MOVB dest_reg, host_reg*/ + addbyte(0x88); + addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); + addbyte(0x88); /*MOVB regs[guest_reg].b, host_reg*/ + addbyte(0x45 | ((host_reg & 3) << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 3].b)); } + } } -static inline void STORE_REG_W_RELEASE(int host_reg) +static __inline void +STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) { + int dest_reg = LOAD_REG_L(guest_reg & 7) & 7; + + if (host_reg & 8) { + addbyte(0x66); /*MOVW guest_reg, host_reg*/ + addbyte(0x45); + addbyte(0x89); + addbyte(0xc0 | dest_reg | ((host_reg & 7) << 3)); + addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 7].w)); + } else { + addbyte(0x66); /*MOVW guest_reg, host_reg*/ + addbyte(0x41); + addbyte(0x89); + addbyte(0xc0 | dest_reg | (host_reg << 3)); + addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ + addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 7].w)); + } +} +static __inline void +STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) +{ + if (host_reg & 8) { + addbyte(0x45); /*MOVL guest_reg, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | guest_reg | (host_reg << 3)); + addbyte(0x44); /*MOVL regs[guest_reg].l, host_reg*/ + addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 7].l)); + } else { + addbyte(0x41); /*MOVL guest_reg, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | guest_reg | (host_reg << 3)); + addbyte(0x89); /*MOVL regs[guest_reg].l, host_reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 7].l)); + } +} + +static __inline void +STORE_REG_B_RELEASE(int host_reg) +{ + if (host_reg & 0x10) { addbyte(0x66); /*MOVW [reg],host_reg*/ addbyte(0x44); addbyte(0x89); addbyte(0x45 | ((host_reg & 7) << 3)); addbyte(cpu_state_offset(regs[host_reg & 7].w)); -} -static inline void STORE_REG_L_RELEASE(int host_reg) -{ - addbyte(0x44); /*MOVL [reg],host_reg*/ - addbyte(0x89); + } else { + addbyte(0x44); /*MOVB [reg],host_reg*/ + addbyte(0x88); addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].l)); + addbyte(cpu_state_offset(regs[host_reg & 7].b)); + } +} +static __inline void +STORE_REG_W_RELEASE(int host_reg) +{ + addbyte(0x66); /*MOVW [reg],host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte(cpu_state_offset(regs[host_reg & 7].w)); +} +static __inline void +STORE_REG_L_RELEASE(int host_reg) +{ + addbyte(0x44); /*MOVL [reg],host_reg*/ + addbyte(0x89); + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte(cpu_state_offset(regs[host_reg & 7].l)); } -static inline void STORE_IMM_REG_B(int reg, uint8_t val) +static __inline void +STORE_IMM_REG_B(int reg, uint8_t val) { - if (reg & 4) - { - int host_reg = LOAD_REG_W(reg & 3) & 7; - addbyte(0x66); /*AND host_reg, 0x00ff*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | host_reg); - addword(0x00ff); - addbyte(0x66); /*OR host_reg, val << 8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xc8 | host_reg); - addword(val << 8); - addbyte(0x66); /*MOVW host_reg, regs[host_reg].w*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 3].w)); - } - else - { - addbyte(0x41); /*MOVB reg, imm*/ - addbyte(0xb0 | reg); - addbyte(val); - addbyte(0x44); /*MOVB reg, regs[reg].b*/ - addbyte(0x88); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].b)); - } -} -static inline void STORE_IMM_REG_W(int reg, uint16_t val) -{ - addbyte(0x66); /*MOVW reg, imm*/ + if (reg & 4) { + int host_reg = LOAD_REG_W(reg & 3) & 7; + addbyte(0x66); /*AND host_reg, 0x00ff*/ addbyte(0x41); - addbyte(0xb8 | reg); - addword(val); - addbyte(0x66); /*MOVW reg, regs[reg].w*/ + addbyte(0x81); + addbyte(0xe0 | host_reg); + addword(0x00ff); + addbyte(0x66); /*OR host_reg, val << 8*/ + addbyte(0x41); + addbyte(0x81); + addbyte(0xc8 | host_reg); + addword(val << 8); + addbyte(0x66); /*MOVW host_reg, regs[host_reg].w*/ addbyte(0x44); addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[reg & 3].w)); + } else { + addbyte(0x41); /*MOVB reg, imm*/ + addbyte(0xb0 | reg); + addbyte(val); + addbyte(0x44); /*MOVB reg, regs[reg].b*/ + addbyte(0x88); addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].w)); + addbyte(cpu_state_offset(regs[reg & 7].b)); + } } -static inline void STORE_IMM_REG_L(int reg, uint32_t val) +static __inline void +STORE_IMM_REG_W(int reg, uint16_t val) { - addbyte(0x41); /*MOVL reg, imm*/ - addbyte(0xb8 | reg); + addbyte(0x66); /*MOVW reg, imm*/ + addbyte(0x41); + addbyte(0xb8 | reg); + addword(val); + addbyte(0x66); /*MOVW reg, regs[reg].w*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | (reg << 3)); + addbyte(cpu_state_offset(regs[reg & 7].w)); +} +static __inline void +STORE_IMM_REG_L(int reg, uint32_t val) +{ + addbyte(0x41); /*MOVL reg, imm*/ + addbyte(0xb8 | reg); + addlong(val); + addbyte(0x44); /*MOVL reg, regs[reg].l*/ + addbyte(0x89); + addbyte(0x45 | (reg << 3)); + addbyte(cpu_state_offset(regs[reg & 7].l)); +} + +static __inline void +STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) +{ + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0xC7); /*MOVL [addr],val*/ + addbyte(0x45); + addbyte(addr - (uintptr_t) &cpu_state - 128); addlong(val); - addbyte(0x44); /*MOVL reg, regs[reg].l*/ - addbyte(0x89); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].l)); + } else if (addr < 0x100000000) { + addbyte(0xC7); /*MOVL [addr],val*/ + addbyte(0x04); + addbyte(0x25); + addlong(addr); + addlong(val); + } else { + addbyte(0x48); /*MOV ESI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad(addr); + addbyte(0xc7); /*MOVL [ESI], val*/ + addbyte(0x00 | REG_ESI); + addlong(val); + } } -static inline void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) +static x86seg * +FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte(addr - (uintptr_t)&cpu_state - 128); - addlong(val); + int mod = (fetchdat >> 6) & 3; + int rm = fetchdat & 7; + + if (!mod && rm == 6) { + addbyte(0xb8); /*MOVL EAX, imm*/ + addlong((fetchdat >> 8) & 0xffff); + (*op_pc) += 2; + } else { + int base_reg = 0, index_reg = 0; + + switch (rm) { + case 0: + case 1: + case 7: + base_reg = LOAD_REG_W(REG_BX); + break; + case 2: + case 3: + case 6: + base_reg = LOAD_REG_W(REG_BP); + break; + case 4: + base_reg = LOAD_REG_W(REG_SI); + break; + case 5: + base_reg = LOAD_REG_W(REG_DI); + break; } - else if (addr < 0x100000000) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x04); - addbyte(0x25); - addlong(addr); - addlong(val); + if (!(rm & 4)) { + if (rm & 1) + index_reg = LOAD_REG_W(REG_DI); + else + index_reg = LOAD_REG_W(REG_SI); } - else - { - addbyte(0x48); /*MOV ESI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad(addr); - addbyte(0xc7); /*MOVL [ESI], val*/ - addbyte(0x00 | REG_ESI); - addlong(val); - } -} + base_reg &= 7; + index_reg &= 7; - - - -static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) -{ - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - - if (!mod && rm == 6) - { - addbyte(0xb8); /*MOVL EAX, imm*/ - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } - else - { - int base_reg = 0, index_reg = 0; - - switch (rm) - { - case 0: case 1: case 7: - base_reg = LOAD_REG_W(REG_BX); - break; - case 2: case 3: case 6: - base_reg = LOAD_REG_W(REG_BP); - break; - case 4: - base_reg = LOAD_REG_W(REG_SI); - break; - case 5: - base_reg = LOAD_REG_W(REG_DI); - break; + switch (mod) { + case 0: + if (rm & 4) { + addbyte(0x41); /*MOVZX EAX, base_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xc0 | base_reg); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ + addbyte(0x43); + addbyte(0x8d); + if (base_reg == 5) { + addbyte(0x44); + addbyte(base_reg | (index_reg << 3)); + addbyte(0); + } else { + addbyte(0x04); + addbyte(base_reg | (index_reg << 3)); + } } - if (!(rm & 4)) - { - if (rm & 1) - index_reg = LOAD_REG_W(REG_DI); - else - index_reg = LOAD_REG_W(REG_SI); + break; + case 1: + if (rm & 4) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x40 | base_reg); + addbyte((fetchdat >> 8) & 0xff); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x44); + addbyte(base_reg | (index_reg << 3)); + addbyte((fetchdat >> 8) & 0xff); } - base_reg &= 7; - index_reg &= 7; - - switch (mod) - { - case 0: - if (rm & 4) - { - addbyte(0x41); /*MOVZX EAX, base_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xc0 | base_reg); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3)); - } - } - break; - case 1: - if (rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte((fetchdat >> 8) & 0xff); - } - (*op_pc)++; - break; - case 2: - if (rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong((fetchdat >> 8) & 0xffff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3)); - addlong((fetchdat >> 8) & 0xffff); - } - (*op_pc) += 2; - break; - - } - if (mod || !(rm & 4)) - { - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - } - - if (mod1seg[rm] == &ss && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - } - return op_ea_seg; -} -static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) -{ - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - uint32_t new_eaaddr; - - if (rm == 4) - { - uint8_t sib = fetchdat >> 8; - int base_reg = -1, index_reg = -1; - (*op_pc)++; - - if (mod || (sib & 7) != 5) - base_reg = LOAD_REG_L(sib & 7) & 7; - - if (((sib >> 3) & 7) != 4) - index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; - - if (index_reg == -1) - { - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOV EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x44); /*MOV EAX, base_reg*/ - addbyte(0x89); - addbyte(0xc0 | (base_reg << 3)); - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x44); - addbyte(0x24); - } - else - { - addbyte(0x40 | base_reg); - } - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x84); - addbyte(0x24); - } - else - { - addbyte(0x80 | base_reg); - } - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } + break; + case 2: + if (rm & 4) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | base_reg); + addlong((fetchdat >> 8) & 0xffff); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x84); + addbyte(base_reg | (index_reg << 3)); + addlong((fetchdat >> 8) & 0xffff); } - else - { - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - if (sib >> 6) - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ - addbyte(0x42); - addbyte(0x8d); - addbyte(0x04); - addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); - addlong(new_eaaddr); - } - else - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | index_reg); - addlong(new_eaaddr); - } - (*op_pc) += 4; - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - } - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; + (*op_pc) += 2; + break; + } + if (mod || !(rm & 4)) { + addbyte(0x25); /*ANDL $0xffff, %eax*/ + addlong(0xffff); } - else - { - int base_reg; - if (!mod && rm == 5) - { + if (mod1seg[rm] == &ss && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } + return op_ea_seg; +} +static x86seg * +FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +{ + int mod = (fetchdat >> 6) & 3; + int rm = fetchdat & 7; + uint32_t new_eaaddr; + + if (rm == 4) { + uint8_t sib = fetchdat >> 8; + int base_reg = -1, index_reg = -1; + + (*op_pc)++; + + if (mod || (sib & 7) != 5) + base_reg = LOAD_REG_L(sib & 7) & 7; + + if (((sib >> 3) & 7) != 4) + index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; + + if (index_reg == -1) { + switch (mod) { + case 0: + if ((sib & 7) == 5) { new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ + addbyte(0xb8); /*MOV EAX, imm32*/ addlong(new_eaaddr); (*op_pc) += 4; - return op_ea_seg; - } - base_reg = LOAD_REG_L(rm) & 7; - if (mod) - { - if (rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (mod == 1) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, base_reg+imm32*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - else - { + } else { addbyte(0x44); /*MOV EAX, base_reg*/ addbyte(0x89); addbyte(0xc0 | (base_reg << 3)); - } + } + break; + case 1: + addbyte(0x67); /*LEA EAX, imm8+base_reg*/ + addbyte(0x41); + addbyte(0x8d); + if (base_reg == 4) { + addbyte(0x44); + addbyte(0x24); + } else { + addbyte(0x40 | base_reg); + } + addbyte((fetchdat >> 16) & 0xff); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, imm32+base_reg*/ + addbyte(0x41); + addbyte(0x8d); + if (base_reg == 4) { + addbyte(0x84); + addbyte(0x24); + } else { + addbyte(0x80 | base_reg); + } + addlong(new_eaaddr); + (*op_pc) += 4; + break; + } + } else { + switch (mod) { + case 0: + if ((sib & 7) == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + if (sib >> 6) { + addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ + addbyte(0x42); + addbyte(0x8d); + addbyte(0x04); + addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); + addlong(new_eaaddr); + } else { + addbyte(0x67); /*LEA EAX, imm32+index_reg*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | index_reg); + addlong(new_eaaddr); + } + (*op_pc) += 4; + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + if (base_reg == 5) { + addbyte(0x44); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addbyte(0); + } else { + addbyte(0x04); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + } + } + break; + case 1: + addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x44); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addbyte((fetchdat >> 16) & 0xff); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x84); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addlong(new_eaaddr); + (*op_pc) += 4; + break; + } } - return op_ea_seg; + if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ + { + addbyte(0x05); + addlong(stack_offset); + } + if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } else { + int base_reg; + + if (!mod && rm == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ + addlong(new_eaaddr); + (*op_pc) += 4; + return op_ea_seg; + } + base_reg = LOAD_REG_L(rm) & 7; + if (mod) { + if (rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (mod == 1) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x40 | base_reg); + addbyte((fetchdat >> 8) & 0xff); + (*op_pc)++; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, base_reg+imm32*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | base_reg); + addlong(new_eaaddr); + (*op_pc) += 4; + } + } else { + addbyte(0x44); /*MOV EAX, base_reg*/ + addbyte(0x89); + addbyte(0xc0 | (base_reg << 3)); + } + } + return op_ea_seg; } -static inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) +static __inline x86seg * +FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) { - if (op_32 & 0x200) - return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); - return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); + if (op_32 & 0x200) + return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); + return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); } - - -static inline void CHECK_SEG_READ(x86seg *seg) +static __inline void +CHECK_SEG_READ(x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - if (IS_32_ADDR(&seg->base)) - { - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x83); /*CMP RSI, -1*/ - addbyte(0xe8 | REG_ESI); - addbyte(0xff); - } - addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ - addbyte(0x84); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_WRITE(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x83); /*CMP RSI, -1*/ - addbyte(0xe8 | REG_ESI); - addbyte(0xff); - } - addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ - addbyte(0x84); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ - addlong((uint32_t)(uintptr_t)seg); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)seg); - } - addbyte(0x3b); /*CMP EAX, seg->limit_low*/ - addbyte(0x46); - addbyte((uintptr_t)&seg->limit_low - (uintptr_t)seg); - addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ - addbyte(0x82); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - if (end_offset) - { - addbyte(0x83); /*ADD EAX, end_offset*/ - addbyte(0xc0); - addbyte(end_offset); - addbyte(0x3b); /*CMP EAX, seg->limit_high*/ - addbyte(0x46); - addbyte((uintptr_t)&seg->limit_high - (uintptr_t)seg); - addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ - addbyte(0x87); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - addbyte(0x83); /*SUB EAX, end_offset*/ - addbyte(0xe8); - addbyte(end_offset); - } -} - -static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); + if (IS_32_ADDR(&seg->base)) { + addbyte(0x83); /*CMP seg->base, -1*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmembl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x83); /*CMP RSI, -1*/ addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x66); /*MOV AX,[RDI+RSI]*/ - addbyte(0x8b); - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemwl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + addbyte(0xff); + } + addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ + addbyte(0x84); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + + seg->checked = 1; } -static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +static __inline void +CHECK_SEG_WRITE(x86seg *seg) { - addbyte(0x83); /*ADD EAX, offset*/ + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; + + if (IS_32_ADDR(&seg->base)) { + addbyte(0x83); /*CMP seg->base, -1*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + addbyte(-1); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x83); /*CMP RSI, -1*/ + addbyte(0xe8 | REG_ESI); + addbyte(0xff); + } + addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ + addbyte(0x84); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + + seg->checked = 1; +} +static __inline void +CHECK_SEG_LIMITS(x86seg *seg, int end_offset) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + return; + + if (IS_32_ADDR(&seg->base)) { + addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ + addlong((uint32_t) (uintptr_t) seg); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) seg); + } + addbyte(0x3b); /*CMP EAX, seg->limit_low*/ + addbyte(0x46); + addbyte((uintptr_t) &seg->limit_low - (uintptr_t) seg); + addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ + addbyte(0x82); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + if (end_offset) { + addbyte(0x83); /*ADD EAX, end_offset*/ addbyte(0xc0); - addbyte(offset); - MEM_LOAD_ADDR_EA_W(seg); + addbyte(end_offset); + addbyte(0x3b); /*CMP EAX, seg->limit_high*/ + addbyte(0x46); + addbyte((uintptr_t) &seg->limit_high - (uintptr_t) seg); + addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ + addbyte(0x87); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + addbyte(0x83); /*SUB EAX, end_offset*/ + addbyte(0xe8); + addbyte(end_offset); + } } -static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) + +static __inline void +MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemll); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x48); /*MOV RAX,[RDI+RSI]*/ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); addbyte(0x8b); - addbyte(0x04); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 2); + addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmembl); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} +static __inline void +MEM_LOAD_ADDR_EA_W(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 2); + addbyte(0x66); /*MOV AX,[RDI+RSI]*/ + addbyte(0x8b); + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemwl); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} +static __inline void +MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +{ + addbyte(0x83); /*ADD EAX, offset*/ + addbyte(0xc0); + addbyte(offset); + MEM_LOAD_ADDR_EA_W(seg); +} +static __inline void +MEM_LOAD_ADDR_EA_L(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 2); + addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemll); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} +static __inline void +MEM_LOAD_ADDR_EA_Q(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 7*/ + addbyte(0xc7); + addlong(7); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 2); + addbyte(0x48); /*MOV RAX,[RDI+RSI]*/ + addbyte(0x8b); + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemql); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} + +static __inline void +MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_B(seg); +} +static __inline void +MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_W(seg); +} +static __inline void +MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_L(seg); +} + +static __inline void +MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) +{ + if (host_reg & 0x10) { + /*Handle high byte of register*/ + if (host_reg & 8) { + addbyte(0x45); /*MOVL R8, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3)); + } else { + addbyte(0x41); /*MOVL R8, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3)); + } + addbyte(0x66); /*SHR R8, 8*/ + addbyte(0x41); + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + host_reg = 8; + } + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 4 : 3) + 2); + if (host_reg & 8) { + addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x88); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemql); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + } else { + addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12 + 4 + 6); + } else { + addbyte(2 + 2 + 2 + 12 + 4 + 6); + } + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + load_param_2_reg_32(host_reg); + call_long((uintptr_t) writemembl); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ } - -static inline void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) +static __inline void +MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_B(seg); -} -static inline void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_W(seg); -} -static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_L(seg); -} - -static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) -{ - if (host_reg & 0x10) - { - /*Handle high byte of register*/ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - addbyte(0x66); /*SHR R8, 8*/ - addbyte(0x41); - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - host_reg = 8; - } - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x88); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12+4+6); - } else { - addbyte(2+2+2+12+4+6); - } - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(host_reg); - call_long((uintptr_t)writemembl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); - if (host_reg & 8) - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12+4+6); - } else { - addbyte(2+2+2+12+4+6); - } - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(host_reg); - call_long((uintptr_t)writememwl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + ((host_reg & 8) ? 5 : 4) + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 5 : 4) + 2); + if (host_reg & 8) { + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12 + 4 + 6); + } else { + addbyte(2 + 2 + 2 + 12 + 4 + 6); + } + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + load_param_2_reg_32(host_reg); + call_long((uintptr_t) writememwl); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ } -static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 4:3)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12+4+6); - } else { - addbyte(2+2+2+12+4+6); - } - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(host_reg); - call_long((uintptr_t)writememll); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + ((host_reg & 8) ? 4 : 3) + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 4 : 3) + 2); + if (host_reg & 8) { + addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12 + 4 + 6); + } else { + addbyte(2 + 2 + 2 + 12 + 4 + 6); + } + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + load_param_2_reg_32(host_reg); + call_long((uintptr_t) writememll); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} +static __inline void +MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 7*/ + addbyte(0xc7); + addlong(7); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 2); + if (host_reg & 8) { + addbyte(0x4c); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x48); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 3 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + load_param_2_reg_64(host_reg); + call_long((uintptr_t) writememql); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} + +static __inline void +MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_B(seg, host_reg); +} +static __inline void +MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_W(seg, host_reg); +} +static __inline void +MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_L(seg, host_reg); +} + +static __inline void +STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) +{ + int temp_reg = REG_ECX; + + if (host_reg_mapping[REG_ECX] != -1) + temp_reg = REG_EBX; + + if (host_reg & 0x10) { if (host_reg & 8) - { - addbyte(0x4c); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x48); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - load_param_2_reg_64(host_reg); - call_long((uintptr_t)writememql); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} - -static inline void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_B(seg, host_reg); -} -static inline void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_W(seg, host_reg); -} -static inline void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_L(seg, host_reg); -} - -static inline void STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) -{ - int temp_reg = REG_ECX; - - if (host_reg_mapping[REG_ECX] != -1) - temp_reg = REG_EBX; - - if (host_reg & 0x10) - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb7); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - addbyte(0xc1); /*SHR temp_reg, 8*/ - addbyte(0xe8 | temp_reg); - addbyte(8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb6); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - } - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x04 | (temp_reg << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - addbyte(0x89); /*MOV [RSI], temp_reg*/ - addbyte(0x06 | (temp_reg << 3)); - } -} -static inline void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) -{ - int temp_reg = REG_ECX; - - if (host_reg_mapping[REG_ECX] != -1) - temp_reg = REG_EBX; - - if (host_reg & 8) - addbyte(0x41); + addbyte(0x41); addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ addbyte(0xb7); addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x04 | (temp_reg << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - addbyte(0x89); /*MOV [RSI], temp_reg*/ - addbyte(0x06 | (temp_reg << 3)); - } -} -static inline void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x66); /*MOVW [addr],host_reg*/ - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x66); - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVW addr,host_reg*/ - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - - addbyte(0x66); - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVW [RSI],host_reg*/ - addbyte(0x06 | ((host_reg & 7) << 3)); - } -} -static inline void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [addr],host_reg*/ - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL addr,host_reg*/ - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [RSI],host_reg*/ - addbyte(0x06 | ((host_reg & 7) << 3)); - } -} - -static inline void AND_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - addbyte(0x66); /*OR AX, 0x00ff*/ - addbyte(0x0d); - addword(0xff); - addbyte(0x66); /*ANDW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ANDB dst_reg, AL*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*OR src_reg, 0xff*/ - addbyte(0x81); - addbyte(0xc8 | src_reg); - addword(0xff); - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x20); /*ANDB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x20); /*ANDB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x20); /*ANDB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } -} -static inline void AND_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void AND_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x21); /*ANDL dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ANDW host_reg, imm<<8*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | (host_reg & 7)); - addword((imm << 8) | 0xff); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xe0 | (host_reg & 7)); - addlong(imm); - } -} - -static inline int TEST_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = (dst_reg & 0x10) | REG_EDX; - } - - AND_HOST_REG_B(dst_reg, src_reg); - - return dst_reg & ~0x10; -} -static inline int TEST_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - AND_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static inline int TEST_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - AND_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} -static inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) -{ + addbyte(0xc1); /*SHR temp_reg, 8*/ + addbyte(0xe8 | temp_reg); + addbyte(8); + } else { if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((host_reg & 7) << 3)); - host_reg = REG_EDX | (host_reg & 0x10); - } - if (host_reg & 0x10) - { - addbyte(0x66); /*ANDW host_reg, imm<<8*/ - addbyte(0x81); - addbyte(0xe0 | (host_reg & 7)); - addword((imm << 8) | 0xff); - } - else - { - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xe0 | (host_reg & 7)); - addlong(imm); - } + addbyte(0x41); + addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ + addbyte(0xb6); + addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); + } + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x89); /*MOV addr, temp_reg*/ + addbyte(0x45 | (temp_reg << 3)); + addbyte((uint32_t) addr - (uint32_t) (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x89); /*MOV addr, temp_reg*/ + addbyte(0x04 | (temp_reg << 3)); + addbyte(0x25); + addlong(addr); + } else { + addbyte(0x48); /*MOV RSI, addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) addr); + addbyte(0x89); /*MOV [RSI], temp_reg*/ + addbyte(0x06 | (temp_reg << 3)); + } +} +static __inline void +STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) +{ + int temp_reg = REG_ECX; - return host_reg; + if (host_reg_mapping[REG_ECX] != -1) + temp_reg = REG_EBX; + + if (host_reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ + addbyte(0xb7); + addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x89); /*MOV addr, temp_reg*/ + addbyte(0x45 | (temp_reg << 3)); + addbyte((uint32_t) addr - (uint32_t) (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x89); /*MOV addr, temp_reg*/ + addbyte(0x04 | (temp_reg << 3)); + addbyte(0x25); + addlong(addr); + } else { + addbyte(0x48); /*MOV RSI, addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) addr); + addbyte(0x89); /*MOV [RSI], temp_reg*/ + addbyte(0x06 | (temp_reg << 3)); + } +} +static __inline void +STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) +{ + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x66); /*MOVW [addr],host_reg*/ + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte((uint32_t) addr - (uint32_t) (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x66); + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVW addr,host_reg*/ + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(0x25); + addlong(addr); + } else { + addbyte(0x48); /*MOV RSI, addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) addr); + + addbyte(0x66); + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVW [RSI],host_reg*/ + addbyte(0x06 | ((host_reg & 7) << 3)); + } +} +static __inline void +STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) +{ + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVL [addr],host_reg*/ + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte((uint32_t) addr - (uint32_t) (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVL addr,host_reg*/ + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(0x25); + addlong(addr); + } else { + addbyte(0x48); /*MOV RSI, addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) addr); + + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVL [RSI],host_reg*/ + addbyte(0x06 | ((host_reg & 7) << 3)); + } } -static inline void OR_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +AND_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*ORW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ORB dst_reg, AL*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } + addbyte(0x66); /*OR AX, 0x00ff*/ + addbyte(0x0d); + addword(0xff); + addbyte(0x66); /*ANDW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*ANDB dst_reg, AL*/ + addbyte(0x20); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*ANDB dst_reg, src_reg*/ + addbyte(0x20); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*OR src_reg, 0xff*/ + addbyte(0x81); + addbyte(0xc8 | src_reg); + addword(0xff); + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*ANDB dst_reg, src_reg*/ + addbyte(0x20); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x08); /*ORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x08); /*ORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x08); /*ORB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (src_reg & 0x10) { + addbyte(0x41); /*MOVZX EBX, src_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x20); /*ANDB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x44); /*ANDB dst_reg, src_reg*/ + addbyte(0x20); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } + } else { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x0f); /*MOVZX EBX, src_reg*/ + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x20); /*ANDB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x20); /*ANDB dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } } -static inline void OR_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +AND_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } } -static inline void OR_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +AND_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x09); /*ORW dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*ANDL dst_reg, src_reg*/ + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*ANDL dst_reg, src_reg*/ + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*ANDL dst_reg, src_reg*/ + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x21); /*ANDL dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } } -static inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline void +AND_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (host_reg & 0x10) - { - addbyte(0x66); /*ORW host_reg, imm<<8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xc8 | (host_reg & 7)); - addword(imm << 8); - } - else if (host_reg & 8) - { - addbyte(0x41); /*ORL host_reg, imm*/ - addbyte(0x81); - addbyte(0xc8 | (host_reg & 7)); - addlong(imm); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xc8 | (host_reg & 7)); - addlong(imm); - } + if (host_reg & 0x10) { + addbyte(0x66); /*ANDW host_reg, imm<<8*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); + addbyte(0xe0 | (host_reg & 7)); + addword((imm << 8) | 0xff); + } else { + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); /*ANDL host_reg, imm*/ + addbyte(0xe0 | (host_reg & 7)); + addlong(imm); + } } -static inline void XOR_HOST_REG_B(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*XORW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*XORB dst_reg, AL*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x30); /*XORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x30); /*XORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x30); /*XORB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = (dst_reg & 0x10) | REG_EDX; + } + + AND_HOST_REG_B(dst_reg, src_reg); + + return dst_reg & ~0x10; } -static inline void XOR_HOST_REG_W(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = REG_EDX; + } + + AND_HOST_REG_W(dst_reg, src_reg); + + return dst_reg; } -static inline void XOR_HOST_REG_L(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*XORL dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*XORL dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*XORW dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x31); /*XORW dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = REG_EDX; + } + + AND_HOST_REG_L(dst_reg, src_reg); + + return dst_reg; } -static inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline int +TEST_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (host_reg & 0x10) - { - addbyte(0x66); /*ORW host_reg, imm<<8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xf0 | (host_reg & 7)); - addword(imm << 8); - } - else if (host_reg & 8) - { - addbyte(0x41); /*ORL host_reg, imm*/ - addbyte(0x81); - addbyte(0xf0 | (host_reg & 7)); - addlong(imm); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xf0 | (host_reg & 7)); - addlong(imm); - } + if (host_reg & 8) { + addbyte(0x44); /*MOV EDX, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((host_reg & 7) << 3)); + host_reg = REG_EDX | (host_reg & 0x10); + } + if (host_reg & 0x10) { + addbyte(0x66); /*ANDW host_reg, imm<<8*/ + addbyte(0x81); + addbyte(0xe0 | (host_reg & 7)); + addword((imm << 8) | 0xff); + } else { + addbyte(0x81); /*ANDL host_reg, imm*/ + addbyte(0xe0 | (host_reg & 7)); + addlong(imm); + } + + return host_reg; } -static inline void ADD_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +OR_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*ADDW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ADDB dst_reg, AL*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } else { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } + addbyte(0x66); /*ORW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*ORB dst_reg, AL*/ + addbyte(0x08); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*ORB dst_reg, src_reg*/ + addbyte(0x08); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*ORB dst_reg, src_reg*/ + addbyte(0x08); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (src_reg & 8) - { - if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x00); /*ADDB dst_reg, AL*/ - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); } - else - fatal("!(dst_reg & src_reg & 8)\n"); + if (src_reg & 0x10) { + addbyte(0x41); /*MOVZX EBX, src_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x08); /*ORB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x44); /*ORB dst_reg, src_reg*/ + addbyte(0x08); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } else { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x0f); /*MOVZX EBX, src_reg*/ + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x08); /*ORB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x08); /*ORB dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } } -static inline void ADD_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +OR_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - fatal("!(dst_reg & src_reg & 8)\n"); + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } } -static inline void ADD_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +OR_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - fatal("!(dst_reg & src_reg & 8)\n"); + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*ORL dst_reg, src_reg*/ + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*ORL dst_reg, src_reg*/ + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*ORL dst_reg, src_reg*/ + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x09); /*ORW dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } +} +static __inline void +OR_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (host_reg & 0x10) { + addbyte(0x66); /*ORW host_reg, imm<<8*/ + addbyte(0x41); + addbyte(0x81); + addbyte(0xc8 | (host_reg & 7)); + addword(imm << 8); + } else if (host_reg & 8) { + addbyte(0x41); /*ORL host_reg, imm*/ + addbyte(0x81); + addbyte(0xc8 | (host_reg & 7)); + addlong(imm); + } else { + addbyte(0x81); /*ORL host_reg, imm*/ + addbyte(0xc8 | (host_reg & 7)); + addlong(imm); + } } -static inline void SUB_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +XOR_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*SUBW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*SUBB dst_reg, AL*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } else { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } + addbyte(0x66); /*XORW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*XORB dst_reg, AL*/ + addbyte(0x30); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*XORB dst_reg, src_reg*/ + addbyte(0x30); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*XORB dst_reg, src_reg*/ + addbyte(0x30); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x28); /*SUBB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x28); /*SUBB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x28); /*SUBB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (src_reg & 0x10) { + addbyte(0x41); /*MOVZX EBX, src_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x30); /*XORB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x44); /*XORB dst_reg, src_reg*/ + addbyte(0x30); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } + } else { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x0f); /*MOVZX EBX, src_reg*/ + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x30); /*XORB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x30); /*XORB dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } } -static inline void SUB_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +XOR_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } } -static inline void SUB_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +XOR_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x29); /*SUBL dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*XORL dst_reg, src_reg*/ + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*XORL dst_reg, src_reg*/ + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*XORW dst_reg, src_reg*/ + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x31); /*XORW dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } +} +static __inline void +XOR_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (host_reg & 0x10) { + addbyte(0x66); /*ORW host_reg, imm<<8*/ + addbyte(0x41); + addbyte(0x81); + addbyte(0xf0 | (host_reg & 7)); + addword(imm << 8); + } else if (host_reg & 8) { + addbyte(0x41); /*ORL host_reg, imm*/ + addbyte(0x81); + addbyte(0xf0 | (host_reg & 7)); + addlong(imm); + } else { + addbyte(0x81); /*ORL host_reg, imm*/ + addbyte(0xf0 | (host_reg & 7)); + addlong(imm); + } } -static inline int CMP_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = (dst_reg & 0x10) | REG_EDX; + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } else { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } + addbyte(0x66); /*ADDW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*ADDB dst_reg, AL*/ + addbyte(0x00); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*ADDB dst_reg, src_reg*/ + addbyte(0x00); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - - SUB_HOST_REG_B(dst_reg, src_reg); - - return dst_reg & ~0x10; + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*ADDB dst_reg, src_reg*/ + addbyte(0x00); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } else if (src_reg & 8) { + if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x00); /*ADDB dst_reg, AL*/ + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x44); /*ADDB dst_reg, src_reg*/ + addbyte(0x00); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } else + fatal("!(dst_reg & src_reg & 8)\n"); } -static inline int CMP_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - SUB_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else + fatal("!(dst_reg & src_reg & 8)\n"); } -static inline int CMP_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - SUB_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*ADDL dst_reg, src_reg*/ + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*ADDL dst_reg, src_reg*/ + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*ADDL dst_reg, src_reg*/ + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else + fatal("!(dst_reg & src_reg & 8)\n"); } -static inline void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline void +SUB_HOST_REG_B(int dst_reg, int src_reg) { - if (host_reg & 0x10) - { - addbyte(0x66); /*ADDW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xC0 | (host_reg & 7)); - addword(imm << 8); + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } else { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } + addbyte(0x66); /*SUBW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*SUBB dst_reg, AL*/ + addbyte(0x28); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*SUBB dst_reg, src_reg*/ + addbyte(0x28); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x80); /*ADDB host_reg, imm*/ - addbyte(0xC0 | (host_reg & 7)); - addbyte(imm); + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*SUBB dst_reg, src_reg*/ + addbyte(0x28); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } + } else if (src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x41); /*MOVZX EBX, src_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x28); /*SUBB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x44); /*SUBB dst_reg, src_reg*/ + addbyte(0x28); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } else { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x0f); /*MOVZX EBX, src_reg*/ + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x28); /*SUBB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x28); /*SUBB dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } } -static inline void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static __inline void +SUB_HOST_REG_W(int dst_reg, int src_reg) { + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } +} +static __inline void +SUB_HOST_REG_L(int dst_reg, int src_reg) +{ + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*SUBL dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*SUBL dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*SUBL dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x29); /*SUBL dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } +} + +static __inline int +CMP_HOST_REG_B(int dst_reg, int src_reg) +{ + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = (dst_reg & 0x10) | REG_EDX; + } + + SUB_HOST_REG_B(dst_reg, src_reg); + + return dst_reg & ~0x10; +} +static __inline int +CMP_HOST_REG_W(int dst_reg, int src_reg) +{ + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = REG_EDX; + } + + SUB_HOST_REG_W(dst_reg, src_reg); + + return dst_reg; +} +static __inline int +CMP_HOST_REG_L(int dst_reg, int src_reg) +{ + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = REG_EDX; + } + + SUB_HOST_REG_L(dst_reg, src_reg); + + return dst_reg; +} + +static __inline void +ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) +{ + if (host_reg & 0x10) { addbyte(0x66); /*ADDW host_reg, imm*/ if (host_reg & 8) - addbyte(0x41); + addbyte(0x41); addbyte(0x81); addbyte(0xC0 | (host_reg & 7)); - addword(imm); -} -static inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) -{ + addword(imm << 8); + } else { if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*ADDL host_reg, imm*/ + addbyte(0x41); + addbyte(0x80); /*ADDB host_reg, imm*/ addbyte(0xC0 | (host_reg & 7)); - addlong(imm); + addbyte(imm); + } +} +static __inline void +ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +{ + addbyte(0x66); /*ADDW host_reg, imm*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); + addbyte(0xC0 | (host_reg & 7)); + addword(imm); +} +static __inline void +ADD_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); /*ADDL host_reg, imm*/ + addbyte(0xC0 | (host_reg & 7)); + addlong(imm); } -static inline void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*SUBW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xE8 | (host_reg & 7)); - addword(imm << 8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x80); /*SUBB host_reg, imm*/ - addbyte(0xE8 | (host_reg & 7)); - addbyte(imm); - } -} -static inline void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static __inline void +SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) { + if (host_reg & 0x10) { addbyte(0x66); /*SUBW host_reg, imm*/ if (host_reg & 8) - addbyte(0x41); + addbyte(0x41); addbyte(0x81); addbyte(0xE8 | (host_reg & 7)); - addword(imm); -} -static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) -{ + addword(imm << 8); + } else { if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*SUBL host_reg, imm*/ + addbyte(0x41); + addbyte(0x80); /*SUBB host_reg, imm*/ addbyte(0xE8 | (host_reg & 7)); - addlong(imm); + addbyte(imm); + } +} +static __inline void +SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) +{ + addbyte(0x66); /*SUBW host_reg, imm*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); + addbyte(0xE8 | (host_reg & 7)); + addword(imm); +} +static __inline void +SUB_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); /*SUBL host_reg, imm*/ + addbyte(0xE8 | (host_reg & 7)); + addlong(imm); } -static inline void INC_HOST_REG_W(int host_reg) +static __inline void +INC_HOST_REG_W(int host_reg) { - addbyte(0x66); /*INCW host_reg*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0xff); - addbyte(0xc0 | (host_reg & 7)); + addbyte(0x66); /*INCW host_reg*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0xff); + addbyte(0xc0 | (host_reg & 7)); } -static inline void INC_HOST_REG(int host_reg) +static __inline void +INC_HOST_REG(int host_reg) { - if (host_reg & 8) - addbyte(0x41); - addbyte(0xff); /*INCL host_reg*/ - addbyte(0xc0 | (host_reg & 7)); + if (host_reg & 8) + addbyte(0x41); + addbyte(0xff); /*INCL host_reg*/ + addbyte(0xc0 | (host_reg & 7)); } -static inline void DEC_HOST_REG_W(int host_reg) +static __inline void +DEC_HOST_REG_W(int host_reg) { - addbyte(0x66); /*DECW host_reg*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0xff); - addbyte(0xc8 | (host_reg & 7)); + addbyte(0x66); /*DECW host_reg*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0xff); + addbyte(0xc8 | (host_reg & 7)); } -static inline void DEC_HOST_REG(int host_reg) +static __inline void +DEC_HOST_REG(int host_reg) { - if (host_reg & 8) - addbyte(0x41); - addbyte(0xff); /*DECL host_reg*/ - addbyte(0xc8 | (host_reg & 7)); + if (host_reg & 8) + addbyte(0x41); + addbyte(0xff); /*DECL host_reg*/ + addbyte(0xc8 | (host_reg & 7)); } -static inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline int +CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) { - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = (host_reg & 0x10) | REG_EDX; - } - - SUB_HOST_REG_IMM_B(host_reg, imm); - - return host_reg; -} -static inline int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = REG_EDX; - } - - SUB_HOST_REG_IMM_W(host_reg, imm); - - return host_reg; -} -static inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = REG_EDX; - } - - SUB_HOST_REG_IMM(host_reg, imm); - - return host_reg; -} - -static inline void LOAD_STACK_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[ESP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} -static inline void LOAD_EBP_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[EBP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_BP].l)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static inline void SP_MODIFY(int off) -{ - if (stack32) - { - if (off < 0x80) - { - addbyte(0x83); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addbyte(off); - } - else - { - addbyte(0x81); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addlong(off); - } - } - else - { - if (off < 0x80) - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x83); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addbyte(off); - } - else - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x81); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addword(off); - } - } -} - -static inline void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - uint8_t *jump1; - - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - CALL_FUNC((uintptr_t)CF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - - if (!not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - if (not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; -} - -static inline void BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - uint8_t *jump1; - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - if (!not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - if (not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; -} - -static inline int LOAD_VAR_W(uintptr_t addr) -{ - int host_reg = REG_EBX; - - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x0f); /*MOVZX host_reg, offset[cpu_state]*/ - addbyte(0xb7); - addbyte(0x45 | (host_reg << 3)); - addbyte(addr - (uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x0f); /*MOVZX host_reg,[reg]*/ - addbyte(0xb7); - addbyte(0x04 | (host_reg << 3)); - addbyte(0x25); - addlong((uint32_t)addr); - } - else - { - addbyte(0x48); /*MOV host_reg, &addr*/ - addbyte(0xb8 | host_reg); - addquad(addr); - addbyte(0x0f); /*MOVZX host_reg, [host_reg]*/ - addbyte(0xb7); - addbyte(host_reg | (host_reg << 3)); - } - - return host_reg; -} -static inline int LOAD_VAR_WL(uintptr_t addr) -{ - return LOAD_VAR_W(addr); -} -static inline int LOAD_VAR_L(uintptr_t addr) -{ - int host_reg = REG_EBX; - - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x8b); /*MOVL host_reg, offset[cpu_state]*/ - addbyte(0x45 | (host_reg << 3)); - addbyte(addr - (uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(0x25); - addlong((uint32_t)addr); - } - else - { - addbyte(0x48); /*MOV host_reg, &addr*/ - addbyte(0xb8 | host_reg); - addquad(addr); - addbyte(0x8b); /*MOVL host_reg, [host_reg]*/ - addbyte(host_reg | (host_reg << 3)); - } - - return host_reg; -} - -static inline int COPY_REG(int src_reg) -{ - if (src_reg & 8) - addbyte(0x44); + if (host_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ addbyte(0x89); - addbyte(0xc0 | REG_ECX | ((src_reg & 7) << 3)); + addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - return REG_ECX | (src_reg & 0x10); + host_reg = (host_reg & 0x10) | REG_EDX; + } + + SUB_HOST_REG_IMM_B(host_reg, imm); + + return host_reg; } - -static inline int LOAD_HOST_REG(int host_reg) +static __inline int +CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) { - if (host_reg & 8) - addbyte(0x44); + if (host_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ addbyte(0x89); - addbyte(0xc0 | REG_EBX | ((host_reg & 7) << 3)); + addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - return REG_EBX | (host_reg & 0x10); + host_reg = REG_EDX; + } + + SUB_HOST_REG_IMM_W(host_reg, imm); + + return host_reg; +} +static __inline int +CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) +{ + if (host_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); + + host_reg = REG_EDX; + } + + SUB_HOST_REG_IMM(host_reg, imm); + + return host_reg; } -static inline int ZERO_EXTEND_W_B(int reg) +static __inline void +LOAD_STACK_TO_EA(int off) { - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVZX EAX, AH*/ - addbyte(0xb6); - addbyte(0xc4); - - return REG_EAX; + if (stack32) { + addbyte(0x8b); /*MOVL EAX,[ESP]*/ + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + if (off) { + addbyte(0x83); /*ADD EAX, off*/ + addbyte(0xc0 | (0 << 3) | REG_EAX); + addbyte(off); } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int ZERO_EXTEND_L_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVZX EAX, AH*/ - addbyte(0xb6); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int ZERO_EXTEND_L_W(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regw*/ + } else { + addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ addbyte(0xb7); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} - -static inline int SIGN_EXTEND_W_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVSX EAX, AH*/ - addbyte(0xbe); - addbyte(0xc4); - - return REG_EAX; + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + if (off) { + addbyte(0x66); /*ADD AX, off*/ + addbyte(0x05); + addword(off); } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; + } } -static inline int SIGN_EXTEND_L_B(int reg) +static __inline void +LOAD_EBP_TO_EA(int off) { - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVSX EAX, AH*/ - addbyte(0xbe); - addbyte(0xc4); - - return REG_EAX; + if (stack32) { + addbyte(0x8b); /*MOVL EAX,[EBP]*/ + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_EBP].l)); + if (off) { + addbyte(0x83); /*ADD EAX, off*/ + addbyte(0xc0 | (0 << 3) | REG_EAX); + addbyte(off); } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int SIGN_EXTEND_L_W(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regw*/ - addbyte(0xbf); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; + } else { + addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ + addbyte(0xb7); + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_BP].l)); + if (off) { + addbyte(0x66); /*ADD AX, off*/ + addbyte(0x05); + addword(off); + } + } } -static inline void SHL_B_IMM(int reg, int count) +static __inline void +SP_MODIFY(int off) { - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SHL AH, count*/ - addbyte(0xe0 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); + if (stack32) { + if (off < 0x80) { + addbyte(0x83); /*ADD [ESP], off*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + addbyte(off); + } else { + addbyte(0x81); /*ADD [ESP], off*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + addlong(off); } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SHL reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); + } else { + if (off < 0x80) { + addbyte(0x66); /*ADD [SP], off*/ + addbyte(0x83); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + addbyte(off); + } else { + addbyte(0x66); /*ADD [SP], off*/ + addbyte(0x81); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + addword(off); } -} -static inline void SHL_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHL reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); -} -static inline void SHL_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SHL reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); -} -static inline void SHR_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SHR AH, count*/ - addbyte(0xe8 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SHR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); - } -} -static inline void SHR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHR reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); -} -static inline void SHR_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SHR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); -} -static inline void SAR_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SAR AH, count*/ - addbyte(0xf8 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SAR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); - } -} -static inline void SAR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SAR reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); -} -static inline void SAR_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SAR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); + } } -static inline void NEG_HOST_REG_B(int reg) +static __inline void +TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) { - if (reg & 0x10) - { - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV BX, reg*/ - addbyte(0xc3 | ((reg & 7) << 3)); - addbyte(0xf6); /*NEG BH*/ - addbyte(0xdf); - if (reg & 8) - addbyte(0x41); - addbyte(0x89); /*MOV reg, BX*/ - addbyte(0xd8 | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xf6); - addbyte(0xd8 | (reg & 7)); - } + addbyte(0x66); /*CMPW host_reg, 0*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x83); + addbyte(0xc0 | 0x38 | (host_reg & 7)); + addbyte(0); + addbyte(0x75); /*JNZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static inline void NEG_HOST_REG_W(int reg) +static __inline void +TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) { - addbyte(0x66); - if (reg & 8) - addbyte(0x41); - addbyte(0xf7); - addbyte(0xd8 | (reg & 7)); -} -static inline void NEG_HOST_REG_L(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xf7); - addbyte(0xd8 | (reg & 7)); + if (host_reg & 8) + addbyte(0x41); + addbyte(0x83); /*CMPW host_reg, 0*/ + addbyte(0xc0 | 0x38 | (host_reg & 7)); + addbyte(0); + addbyte(0x75); /*JNZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } - -static inline void FP_ENTER() +static __inline void +TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) { - if (codegen_fpu_entered) - return; - if (IS_32_ADDR(&cr0)) - { - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x04); - addbyte(0x25); - addlong((uintptr_t)&cr0); - addbyte(0x0c); - } - else - { - addbyte(0x48); /*MOV RAX, &cr0*/ - addbyte(0xb8 | REG_EAX); - addquad((uint64_t)&cr0); - addbyte(0xf6); /*TEST [RAX], 0xc*/ - addbyte(0 | (REG_EAX << 3)); - addbyte(0x0c); - } + addbyte(0x66); /*CMPW host_reg, 0*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x83); + addbyte(0xc0 | 0x38 | (host_reg & 7)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} +static __inline void +TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +{ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x83); /*CMPW host_reg, 0*/ + addbyte(0xc0 | 0x38 | (host_reg & 7)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} + +static __inline void +BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) +{ + uint8_t *jump1; + + if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { + addbyte(0x83); /*CMP flags_res, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(flags_res)); + addbyte(0); addbyte(0x74); /*JZ +*/ - addbyte(7+5+12+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC((uintptr_t)x86_int); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + } else { + CALL_FUNC((uintptr_t) ZF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x75); /*JNZ +*/ + } + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + CALL_FUNC((uintptr_t) CF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (timing_bt ? 4 : 0)); - codegen_fpu_entered = 1; + if (!not ) + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + if (not ) + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; } -static inline void FP_FXCH(int reg) +static __inline void +BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); + CALL_FUNC((uintptr_t) NF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE BL*/ + addbyte(0x95); + addbyte(0xc3); + CALL_FUNC((uintptr_t) VF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE AL*/ + addbyte(0x95); + addbyte(0xc0); + addbyte(0x38); /*CMP AL, BL*/ + addbyte(0xd8); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} + +static __inline void +BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) +{ + uint8_t *jump1; + if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { + addbyte(0x83); /*CMP flags_res, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(flags_res)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + } else { + CALL_FUNC((uintptr_t) ZF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x75); /*JNZ +*/ + } + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + CALL_FUNC((uintptr_t) NF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE BL*/ + addbyte(0x95); + addbyte(0xc3); + CALL_FUNC((uintptr_t) VF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE AL*/ + addbyte(0x95); + addbyte(0xc0); + addbyte(0x38); /*CMP AL, BL*/ + addbyte(0xd8); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + if (!not ) + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + if (not ) + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; +} + +static __inline int +LOAD_VAR_W(uintptr_t addr) +{ + int host_reg = REG_EBX; + + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x0f); /*MOVZX host_reg, offset[cpu_state]*/ + addbyte(0xb7); + addbyte(0x45 | (host_reg << 3)); + addbyte(addr - (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x0f); /*MOVZX host_reg,[reg]*/ + addbyte(0xb7); + addbyte(0x04 | (host_reg << 3)); + addbyte(0x25); + addlong((uint32_t) addr); + } else { + addbyte(0x48); /*MOV host_reg, &addr*/ + addbyte(0xb8 | host_reg); + addquad(addr); + addbyte(0x0f); /*MOVZX host_reg, [host_reg]*/ + addbyte(0xb7); + addbyte(host_reg | (host_reg << 3)); + } + + return host_reg; +} +static __inline int +LOAD_VAR_WL(uintptr_t addr) +{ + return LOAD_VAR_W(addr); +} +static __inline int +LOAD_VAR_L(uintptr_t addr) +{ + int host_reg = REG_EBX; + + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x8b); /*MOVL host_reg, offset[cpu_state]*/ + addbyte(0x45 | (host_reg << 3)); + addbyte(addr - (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x8b); /*MOVL host_reg,[reg]*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(0x25); + addlong((uint32_t) addr); + } else { + addbyte(0x48); /*MOV host_reg, &addr*/ + addbyte(0xb8 | host_reg); + addquad(addr); + addbyte(0x8b); /*MOVL host_reg, [host_reg]*/ + addbyte(host_reg | (host_reg << 3)); + } + + return host_reg; +} + +static __inline int +COPY_REG(int src_reg) +{ + if (src_reg & 8) + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | REG_ECX | ((src_reg & 7) << 3)); + + return REG_ECX | (src_reg & 0x10); +} + +static __inline int +LOAD_HOST_REG(int host_reg) +{ + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | REG_EBX | ((host_reg & 7) << 3)); + + return REG_EBX | (host_reg & 0x10); +} + +static __inline int +ZERO_EXTEND_W_B(int reg) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | (reg << 3)); + addbyte(0x0f); /*MOVZX EAX, AH*/ + addbyte(0xb6); + addbyte(0xc4); + + return REG_EAX; + } + + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVZX regl, regb*/ + addbyte(0xb6); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} +static __inline int +ZERO_EXTEND_L_B(int reg) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | (reg << 3)); + addbyte(0x0f); /*MOVZX EAX, AH*/ + addbyte(0xb6); + addbyte(0xc4); + + return REG_EAX; + } + + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVZX regl, regb*/ + addbyte(0xb6); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} +static __inline int +ZERO_EXTEND_L_W(int reg) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVZX regl, regw*/ + addbyte(0xb7); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} + +static __inline int +SIGN_EXTEND_W_B(int reg) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | (reg << 3)); + addbyte(0x0f); /*MOVSX EAX, AH*/ + addbyte(0xbe); + addbyte(0xc4); + + return REG_EAX; + } + + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVSX regl, regb*/ + addbyte(0xbe); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} +static __inline int +SIGN_EXTEND_L_B(int reg) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | (reg << 3)); + addbyte(0x0f); /*MOVSX EAX, AH*/ + addbyte(0xbe); + addbyte(0xc4); + + return REG_EAX; + } + + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVSX regl, regb*/ + addbyte(0xbe); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} +static __inline int +SIGN_EXTEND_L_W(int reg) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVSX regl, regw*/ + addbyte(0xbf); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} + +static __inline void +SHL_B_IMM(int reg, int count) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); + addbyte(0xc0); /*SHL AH, count*/ + addbyte(0xe0 | REG_AH); + addbyte(count); + addbyte(0x41); /*MOV reg, EAX*/ + addbyte(0x89); + addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); + } else { + if (reg & 8) + addbyte(0x41); + addbyte(0xc0); /*SHL reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x20); + addbyte(count); + } +} +static __inline void +SHL_W_IMM(int reg, int count) +{ + addbyte(0x66); /*SHL reg, count*/ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); + addbyte(0xc0 | (reg & 7) | 0x20); + addbyte(count); +} +static __inline void +SHL_L_IMM(int reg, int count) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); /*SHL reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x20); + addbyte(count); +} +static __inline void +SHR_B_IMM(int reg, int count) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); + addbyte(0xc0); /*SHR AH, count*/ + addbyte(0xe8 | REG_AH); + addbyte(count); + addbyte(0x41); /*MOV reg, EAX*/ + addbyte(0x89); + addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); + } else { + if (reg & 8) + addbyte(0x41); + addbyte(0xc0); /*SHR reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x28); + addbyte(count); + } +} +static __inline void +SHR_W_IMM(int reg, int count) +{ + addbyte(0x66); /*SHR reg, count*/ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); + addbyte(0xc0 | (reg & 7) | 0x28); + addbyte(count); +} +static __inline void +SHR_L_IMM(int reg, int count) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); /*SHR reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x28); + addbyte(count); +} +static __inline void +SAR_B_IMM(int reg, int count) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); + addbyte(0xc0); /*SAR AH, count*/ + addbyte(0xf8 | REG_AH); + addbyte(count); + addbyte(0x41); /*MOV reg, EAX*/ + addbyte(0x89); + addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); + } else { + if (reg & 8) + addbyte(0x41); + addbyte(0xc0); /*SAR reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x38); + addbyte(count); + } +} +static __inline void +SAR_W_IMM(int reg, int count) +{ + addbyte(0x66); /*SAR reg, count*/ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); + addbyte(0xc0 | (reg & 7) | 0x38); + addbyte(count); +} +static __inline void +SAR_L_IMM(int reg, int count) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); /*SAR reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x38); + addbyte(count); +} + +static __inline void +NEG_HOST_REG_B(int reg) +{ + if (reg & 0x10) { + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV BX, reg*/ + addbyte(0xc3 | ((reg & 7) << 3)); + addbyte(0xf6); /*NEG BH*/ + addbyte(0xdf); + if (reg & 8) + addbyte(0x41); + addbyte(0x89); /*MOV reg, BX*/ + addbyte(0xd8 | (reg & 7)); + } else { + if (reg & 8) + addbyte(0x41); + addbyte(0xf6); + addbyte(0xd8 | (reg & 7)); + } +} +static __inline void +NEG_HOST_REG_W(int reg) +{ + addbyte(0x66); + if (reg & 8) + addbyte(0x41); + addbyte(0xf7); + addbyte(0xd8 | (reg & 7)); +} +static __inline void +NEG_HOST_REG_L(int reg) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0xf7); + addbyte(0xd8 | (reg & 7)); +} + +static __inline void +FP_ENTER(void) +{ + if (codegen_fpu_entered) + return; + if (IS_32_ADDR(&cr0)) { + addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0x04); + addbyte(0x25); + addlong((uintptr_t) &cr0); + addbyte(0x0c); + } else { + addbyte(0x48); /*MOV RAX, &cr0*/ + addbyte(0xb8 | REG_EAX); + addquad((uint64_t) &cr0); + addbyte(0xf6); /*TEST [RAX], 0xc*/ + addbyte(0 | (REG_EAX << 3)); + addbyte(0x0c); + } + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + 12 + 5); + addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(op_old_pc); + load_param_1_32(&codeblock[block_current], 7); + CALL_FUNC((uintptr_t) x86_int); + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + + codegen_fpu_entered = 1; +} + +static __inline void +FP_FXCH(int reg) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + + addbyte(0x48); /*MOV RDX, ST[RBX*8]*/ + addbyte(0x8b); + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + addbyte(0x48); /*MOV RCX, ST[RAX*8]*/ + addbyte(0x8b); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x48); /*MOV ST[RAX*8], RDX*/ + addbyte(0x89); + addbyte(0x54); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x48); /*MOV ST[RBX*8], RCX*/ + addbyte(0x89); + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + + addbyte(0x8a); /*MOV CL, tag[EAX]*/ + addbyte(0x4c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(0x8a); /*MOV DL, tag[EBX]*/ + addbyte(0x54); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(0x88); /*MOV tag[EBX], CL*/ + addbyte(0x4c); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(0x88); /*MOV tag[EAX], DL*/ + addbyte(0x54); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + + addbyte(0x48); /*MOV RDX, MM[RBX*8]*/ + addbyte(0x8b); + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x48); /*MOV RCX, MM[RAX*8]*/ + addbyte(0x8b); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x48); /*MOV MM[RAX*8], RDX*/ + addbyte(0x89); + addbyte(0x54); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x48); /*MOV MM[RBX*8], RCX*/ + addbyte(0x89); + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); +} + +static __inline void +FP_FLD(int reg) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (reg) { addbyte(0x83); /*ADD EAX, reg*/ addbyte(0xc0); addbyte(reg); - - addbyte(0x48); /*MOV RDX, ST[RBX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); addbyte(0x83); /*AND EAX, 7*/ addbyte(0xe0); addbyte(0x07); - addbyte(0x48); /*MOV RCX, ST[RAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST[RAX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST[RBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); + } else { + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + } - addbyte(0x8a); /*MOV CL, tag[EAX]*/ - addbyte(0x4c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x8a); /*MOV DL, tag[EBX]*/ - addbyte(0x54); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x88); /*MOV tag[EBX], CL*/ - addbyte(0x4c); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x88); /*MOV tag[EAX], DL*/ - addbyte(0x54); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ + addbyte(0x8b); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(0x07); + addbyte(0x48); /*MOV RDX, ST_i64[EAX*8]*/ + addbyte(0x8b); + addbyte(0x54); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x8a); /*MOV AL, [tag+EAX]*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(0x48); /*MOV ST[EBX*8], RCX*/ + addbyte(0x89); + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x48); /*MOV ST_i64[EBX*8], RDX*/ + addbyte(0x89); + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x88); /*MOV [tag+EBX], AL*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); - addbyte(0x48); /*MOV RDX, MM[RBX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV RCX, MM[RAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV MM[RAX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV MM[RBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); + addbyte(0x89); /*MOV [TOP], EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); } - - -static inline void FP_FLD(int reg) +static __inline void +FP_FST(int reg) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - else - { - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - } + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ + addbyte(0x8b); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [tag+EAX]*/ + addbyte(0x5c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); - addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); addbyte(0x07); - addbyte(0x48); /*MOV RDX, ST_i64[EAX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x8a); /*MOV AL, [tag+EAX]*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x48); /*MOV ST[EBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST_i64[EBX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); + } - addbyte(0x89); /*MOV [TOP], EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); + addbyte(0x48); /*MOV ST[EAX*8], RCX*/ + addbyte(0x89); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x88); /*MOV [tag+EAX], BL*/ + addbyte(0x5c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); } -static inline void FP_FST(int reg) +static __inline void +FP_POP(void) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [tag+EAX]*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - - addbyte(0x48); /*MOV ST[EAX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EAX], BL*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOVB tag[EAX], 3*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(3); + addbyte(0x83); /*ADD AL, 1*/ + addbyte(0xc0); + addbyte(1); + addbyte(0x83); /*AND AL, 7*/ + addbyte(0xe0); + addbyte(7); + addbyte(0x89); /*MOV [TOP], EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); +} +static __inline void +FP_POP2(void) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOVB tag[EAX], 3*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(3); + addbyte(0x83); /*ADD AL, 2*/ + addbyte(0xc0); + addbyte(2); + addbyte(0x83); /*AND AL, 7*/ + addbyte(0xe0); + addbyte(7); + addbyte(0x89); /*MOV [TOP], EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); } -static inline void FP_POP() +static __inline void +FP_LOAD_S(void) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(3); - addbyte(0x83); /*ADD AL, 1*/ - addbyte(0xc0); - addbyte(1); - addbyte(0x83); /*AND AL, 7*/ - addbyte(0xe0); - addbyte(7); - addbyte(0x89); /*MOV [TOP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x66); /*MOVD XMM0, EAX*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc0); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0xf3); /*CVTSS2SD XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x5a); + addbyte(0xc0); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); } -static inline void FP_POP2() +static __inline void +FP_LOAD_D(void) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(3); - addbyte(0x83); /*ADD AL, 2*/ - addbyte(0xc0); - addbyte(2); - addbyte(0x83); /*AND AL, 7*/ - addbyte(0xe0); - addbyte(7); - addbyte(0x89); /*MOV [TOP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x48); /*TEST RAX, RAX*/ + addbyte(0x85); + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x48); /*MOVQ [ST+EBX*8], RAX*/ + addbyte(0x89); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); } -static inline void FP_LOAD_S() +static __inline void +FP_LOAD_IW(void) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf3); /*CVTSS2SD XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x0f); /*MOVSX EAX, AX*/ + addbyte(0xbf); + addbyte(0xc0); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc0); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); } -static inline void FP_LOAD_D() +static __inline void +FP_LOAD_IL(void) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x48); /*TEST RAX, RAX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x48); /*MOVQ [ST+EBX*8], RAX*/ - addbyte(0x89); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc0); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); +} +static __inline void +FP_LOAD_IQ(void) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0xf2); /*CVTSI2SDQ XMM0, RAX*/ + addbyte(0x48); + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc0); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x48); /*TEST RAX, RAX*/ + addbyte(0x85); + addbyte(0xc0); + addbyte(0x48); /*MOV [ST_i64+EBX*8], RAX*/ + addbyte(0x89); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x0f); /*SETE AL*/ + addbyte(0x94); + addbyte(0xc0); + addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0c); /*OR AL, TAG_UINT64*/ + addbyte(TAG_UINT64); + addbyte(0x88); /*MOV [tag+EBX], AL*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); } -static inline void FP_LOAD_IW() +static __inline void +FP_LOAD_IMM_Q(uint64_t v) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static inline void FP_LOAD_IL() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static inline void FP_LOAD_IQ() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SDQ XMM0, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x48); /*TEST RAX, RAX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0x48); /*MOV [ST_i64+EBX*8], RAX*/ - addbyte(0x89); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x0f); /*SETE AL*/ - addbyte(0x94); - addbyte(0xc0); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0c); /*OR AL, TAG_UINT64*/ - addbyte(TAG_UINT64); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addlong(v & 0xffffffff); + addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST) + 4); + addlong(v >> 32); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOV [tag+EBX], (v ? 0 : 1)*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(v ? 0 : 1); } -static inline void FP_LOAD_IMM_Q(uint64_t v) +static __inline void +FP_FCHS(void) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addlong(v & 0xffffffff); - addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST) + 4); - addlong(v >> 32); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOV [tag+EBX], (v ? 0 : 1)*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(v ? 0 : 1); + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xf2); /*SUBSD XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0xc0); + addbyte(0xf2); /*SUBSD XMM0, ST[EAX*8]*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xf2); /*MOVSD ST[EAX*8], XMM0*/ + addbyte(0x0f); + addbyte(0x11); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); } -static inline void FP_FCHS() +static __inline int +FP_LOAD_REG(int reg) { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xf2); /*SUBSD XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc0); - addbyte(0xf2); /*SUBSD XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xf2); /*MOVSD ST[EAX*8], XMM0*/ - addbyte(0x0f); - addbyte(0x11); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); -} - -static inline int FP_LOAD_REG(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xf2); /*CVTSD2SS XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc0); - addbyte(0x66); /*MOVD EBX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ addbyte(0xc0 | REG_EBX); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe0 | REG_EBX); + addbyte(0x07); + } + addbyte(0xf3); /*MOVQ XMM0, ST[EBX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xf2); /*CVTSD2SS XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x5a); + addbyte(0xc0); + addbyte(0x66); /*MOVD EBX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0 | REG_EBX); - return REG_EBX; + return REG_EBX; } -static inline void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) +static __inline void +FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0x48); /*MOV RBX, ST[EBX*8]*/ - addbyte(0x8b); - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc0 | REG_EBX); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe0 | REG_EBX); + addbyte(0x07); + } + addbyte(0x48); /*MOV RBX, ST[EBX*8]*/ + addbyte(0x8b); + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); - *host_reg1 = REG_EBX; + *host_reg1 = REG_EBX; } -static inline int64_t x87_fround16_64(double b) +static __inline int64_t +x87_fround16_64(double b) { - int16_t a, c; + int16_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int16_t)floor(b); - c = (int16_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return (int64_t) a; - else if ((b - a) > (c - b)) - return (int64_t) c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)((int16_t)floor(b)); - case 2: /*Up*/ - return (int64_t)((int16_t)ceil(b)); - case 3: /*Chop*/ - return (int64_t)((int16_t)b); - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int16_t) floor(b); + c = (int16_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return (int64_t) a; + else if ((b - a) > (c - b)) + return (int64_t) c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) ((int16_t) floor(b)); + case 2: /*Up*/ + return (int64_t) ((int16_t) ceil(b)); + case 3: /*Chop*/ + return (int64_t) ((int16_t) b); + } - return 0; + return 0; } -static inline int64_t x87_fround32_64(double b) +static __inline int64_t +x87_fround32_64(double b) { - int32_t a, c; + int32_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int32_t)floor(b); - c = (int32_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return (int64_t) a; - else if ((b - a) > (c - b)) - return (int64_t) c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)((int32_t)floor(b)); - case 2: /*Up*/ - return (int64_t)((int32_t)ceil(b)); - case 3: /*Chop*/ - return (int64_t)((int32_t)b); - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int32_t) floor(b); + c = (int32_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return (int64_t) a; + else if ((b - a) > (c - b)) + return (int64_t) c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) ((int32_t) floor(b)); + case 2: /*Up*/ + return (int64_t) ((int32_t) ceil(b)); + case 3: /*Chop*/ + return (int64_t) ((int32_t) b); + } - return 0; + return 0; } -static inline int64_t x87_fround(double b) +static __inline int64_t +x87_fround(double b) { - int64_t a, c; + int64_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int64_t) floor(b); + c = (int64_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) floor(b); + case 2: /*Up*/ + return (int64_t) ceil(b); + case 3: /*Chop*/ + return (int64_t) b; + } - return 0; + return 0; } -static inline int FP_LOAD_REG_INT_W(int reg) +static __inline int +FP_LOAD_REG_INT_W(int reg) { - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); - CALL_FUNC((uintptr_t)x87_fround16_64); + CALL_FUNC((uintptr_t) x87_fround16_64); - addbyte(0x93); /*XCHG EBX, EAX*/ + addbyte(0x93); /*XCHG EBX, EAX*/ - return REG_EBX; + return REG_EBX; } -static inline int FP_LOAD_REG_INT(int reg) +static __inline int +FP_LOAD_REG_INT(int reg) { - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); - CALL_FUNC((uintptr_t)x87_fround32_64); + CALL_FUNC((uintptr_t) x87_fround32_64); - addbyte(0x93); /*XCHG EBX, EAX*/ + addbyte(0x93); /*XCHG EBX, EAX*/ - return REG_EBX; + return REG_EBX; } -static inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) +static __inline void +FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) { - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) - { - /*If we know the register was loaded with FILDq in this block and - has not been modified, then we can skip most of the conversion - and just load the 64-bit integer representation directly */ - addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ - addbyte(0x8b); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0x48); /*XCHG RBX, RAX*/ - addbyte(0x93); - - *host_reg1 = REG_EBX; - - return; - } - - addbyte(0xf6); /*TEST TAG[EAX], TAG_UINT64*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(TAG_UINT64); - - addbyte(0x74); /*JZ +*/ - addbyte(5+2); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) { + /*If we know the register was loaded with FILDq in this block and + has not been modified, then we can skip most of the conversion + and just load the 64-bit integer representation directly */ addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ addbyte(0x8b); addbyte(0x44); addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0xeb); /*JMP done*/ - addbyte(6+12); - - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - - CALL_FUNC((uintptr_t)x87_fround); + addbyte((uint8_t) cpu_state_offset(MM)); addbyte(0x48); /*XCHG RBX, RAX*/ addbyte(0x93); *host_reg1 = REG_EBX; + + return; + } + + addbyte(0xf6); /*TEST TAG[EAX], TAG_UINT64*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(TAG_UINT64); + + addbyte(0x74); /*JZ +*/ + addbyte(5 + 2); + + addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ + addbyte(0x8b); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + + addbyte(0xeb); /*JMP done*/ + addbyte(6 + 12); + + addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + + CALL_FUNC((uintptr_t) x87_fround); + + addbyte(0x48); /*XCHG RBX, RAX*/ + addbyte(0x93); + + *host_reg1 = REG_EBX; } #define FPU_ADD 0 @@ -4526,1793 +4155,1695 @@ static inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) #define FPU_SUB 2 #define FPU_SUBR 3 -static inline void FP_OP_REG(int op, int dst, int src) +static __inline void +FP_OP_REG(int op, int dst, int src) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (dst) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - if (src) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(src); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(TAG_NOT_UINT64); - if (op == FPU_DIVR || op == FPU_SUBR) - { - addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - switch (op) - { - case FPU_ADD: - addbyte(0xf2); /*ADDSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x58); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_DIV: - addbyte(0xf2); /*DIVSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_DIVR: - addbyte(0xf2); /*DIVSD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_MUL: - addbyte(0xf2); /*MULSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x59); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_SUB: - addbyte(0xf2); /*SUBSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_SUBR: - addbyte(0xf2); /*SUBSD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - } - addbyte(0x66); /*MOVQ [RSI+RAX*8], XMM0*/ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (dst) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + } + if (src) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc0 | REG_EBX); + addbyte(src); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe0 | REG_EBX); + addbyte(0x07); + } + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(TAG_NOT_UINT64); + if (op == FPU_DIVR || op == FPU_SUBR) { + addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } + switch (op) { + case FPU_ADD: + addbyte(0xf2); /*ADDSD XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x58); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_DIV: + addbyte(0xf2); /*DIVSD XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x5e); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_DIVR: + addbyte(0xf2); /*DIVSD XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x5e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_MUL: + addbyte(0xf2); /*MULSD XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x59); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_SUB: + addbyte(0xf2); /*SUBSD XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_SUBR: + addbyte(0xf2); /*SUBSD XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + } + addbyte(0x66); /*MOVQ [RSI+RAX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); +} + +static __inline void +FP_OP_MEM(int op) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(TAG_NOT_UINT64); + + switch (op) { + case FPU_ADD: + addbyte(0xf2); /*ADDSD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x58); + addbyte(0xc1); + break; + case FPU_DIV: + addbyte(0xf2); /*DIVSD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x5e); + addbyte(0xc1); + break; + case FPU_DIVR: + addbyte(0xf2); /*DIVSD XMM1, XMM0*/ + addbyte(0x0f); + addbyte(0x5e); + addbyte(0xc8); + break; + case FPU_MUL: + addbyte(0xf2); /*MULSD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x59); + addbyte(0xc1); + break; + case FPU_SUB: + addbyte(0xf2); /*SUBSD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0xc1); + break; + case FPU_SUBR: + addbyte(0xf2); /*SUBSD XMM1, XMM0*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0xc8); + break; + } + if (op == FPU_DIVR || op == FPU_SUBR) { + addbyte(0x66); /*MOVQ ST[RAX*8], XMM1*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0x66); /*MOVQ ST[RAX*8], XMM0*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x44); addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte((uint8_t) cpu_state_offset(ST)); + } } -static inline void FP_OP_MEM(int op) +static __inline void +FP_OP_S(int op) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); + addbyte(0x66); /*MOVD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc8); + addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ + addbyte(0x0f); + addbyte(0x5a); + addbyte(0xc9); + FP_OP_MEM(op); +} +static __inline void +FP_OP_D(int op) +{ + addbyte(0x66); /*MOVQ XMM1, RAX*/ + addbyte(0x48); + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc8); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0x0f); /*STMXCSR [ESP+8]*/ + addbyte(0xae); + addbyte(0x5c); + addbyte(0x24); + addbyte(0x08); + addbyte(0x8b); /*MOV EAX, [ESP+8]*/ addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(TAG_NOT_UINT64); - - switch (op) - { - case FPU_ADD: - addbyte(0xf2); /*ADDSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x58); - addbyte(0xc1); - break; - case FPU_DIV: - addbyte(0xf2); /*DIVSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0xc1); - break; - case FPU_DIVR: - addbyte(0xf2); /*DIVSD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0xc8); - break; - case FPU_MUL: - addbyte(0xf2); /*MULSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x59); - addbyte(0xc1); - break; - case FPU_SUB: - addbyte(0xf2); /*SUBSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc1); - break; - case FPU_SUBR: - addbyte(0xf2); /*SUBSD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc8); - break; - } - if (op == FPU_DIVR || op == FPU_SUBR) - { - addbyte(0x66); /*MOVQ ST[RAX*8], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0x66); /*MOVQ ST[RAX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } + addbyte(0x24); + addbyte(0x08); + addbyte(0x25); /*AND EAX, ~(3 << 13)*/ + addlong(~(3 << 10)); + addbyte(0x0d); /*OR EAX, (npxc & (3 << 10)) << 3*/ + addlong((cpu_state.npxc & (3 << 10)) << 3); + addbyte(0x89); /*MOV [RSP+12], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x0c); + addbyte(0x0f); /*LDMXCSR [RSP+12]*/ + addbyte(0xae); + addbyte(0x54); + addbyte(0x24); + addbyte(0x0c); + } + FP_OP_MEM(op); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0x0f); /*LDMXCSR [RSP+8]*/ + addbyte(0xae); + addbyte(0x54); + addbyte(0x24); + addbyte(0x08); + } +} +static __inline void +FP_OP_IW(int op) +{ + addbyte(0x0f); /*MOVSX EAX, AX*/ + addbyte(0xbf); + addbyte(0xc0); + addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc8); + FP_OP_MEM(op); +} +static __inline void +FP_OP_IL(int op) +{ + addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc8); + FP_OP_MEM(op); } -static inline void FP_OP_S(int op) +static __inline void +FP_COMPARE_REG(int dst, int src) { - addbyte(0x66); /*MOVD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc9); - FP_OP_MEM(op); -} -static inline void FP_OP_D(int op) -{ - addbyte(0x66); /*MOVQ XMM1, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0x0f); /*STMXCSR [ESP+8]*/ - addbyte(0xae); - addbyte(0x5c); - addbyte(0x24); - addbyte(0x08); - addbyte(0x8b); /*MOV EAX, [ESP+8]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x08); - addbyte(0x25); /*AND EAX, ~(3 << 13)*/ - addlong(~(3 << 10)); - addbyte(0x0d); /*OR EAX, (npxc & (3 << 10)) << 3*/ - addlong((cpu_state.npxc & (3 << 10)) << 3); - addbyte(0x89); /*MOV [RSP+12], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x0c); - addbyte(0x0f); /*LDMXCSR [RSP+12]*/ - addbyte(0xae); - addbyte(0x54); - addbyte(0x24); - addbyte(0x0c); - } - FP_OP_MEM(op); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0x0f); /*LDMXCSR [RSP+8]*/ - addbyte(0xae); - addbyte(0x54); - addbyte(0x24); - addbyte(0x08); - } -} -static inline void FP_OP_IW(int op) -{ - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (src || dst) { + addbyte(0x83); /*ADD EAX, 1*/ addbyte(0xc0); - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_OP_MEM(op); -} -static inline void FP_OP_IL(int op) -{ - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_OP_MEM(op); -} + addbyte(src ? src : dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } -static inline void FP_COMPARE_REG(int dst, int src) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0 | C2 | C3)) >> 8); - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - - if (src) - { - addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x66); /*COMISD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x66); /*COMISD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - - addbyte(0x9f); /*LAHF*/ - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -} - -static inline void FP_COMPARE_MEM() -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ + if (src) { + addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ addbyte(0x0f); addbyte(0x7e); addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0x66); /*COMISD XMM0, XMM1*/ + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x66); /*COMISD XMM0, ST[RAX*8]*/ addbyte(0x0f); addbyte(0x2f); - addbyte(0xc1); - addbyte(0x9f); /*LAHF*/ - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -} -static inline void FP_COMPARE_S() -{ - addbyte(0x66); /*MOVD XMM1, EAX*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x66); /*COMISD XMM0, ST[RBX*8]*/ addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc9); - FP_COMPARE_MEM(); -} -static inline void FP_COMPARE_D() -{ - addbyte(0x66); /*MOVQ XMM1, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - FP_COMPARE_MEM(); -} -static inline void FP_COMPARE_IW() -{ - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_COMPARE_MEM(); -} -static inline void FP_COMPARE_IL() -{ - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_COMPARE_MEM(); + addbyte(0x2f); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } + + addbyte(0x9f); /*LAHF*/ + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); } -static inline void UPDATE_NPXC(int reg) +static __inline void +FP_COMPARE_MEM(void) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0x66); /*COMISD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x2f); + addbyte(0xc1); + addbyte(0x9f); /*LAHF*/ + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); +} +static __inline void +FP_COMPARE_S(void) +{ + addbyte(0x66); /*MOVD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc8); + addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ + addbyte(0x0f); + addbyte(0x5a); + addbyte(0xc9); + FP_COMPARE_MEM(); +} +static __inline void +FP_COMPARE_D(void) +{ + addbyte(0x66); /*MOVQ XMM1, RAX*/ + addbyte(0x48); + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc8); + FP_COMPARE_MEM(); +} +static __inline void +FP_COMPARE_IW(void) +{ + addbyte(0x0f); /*MOVSX EAX, AX*/ + addbyte(0xbf); + addbyte(0xc0); + addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc8); + FP_COMPARE_MEM(); +} +static __inline void +FP_COMPARE_IL(void) +{ + addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc8); + FP_COMPARE_MEM(); +} + +static __inline void +UPDATE_NPXC(int reg) { } -static inline void SET_BITS(uintptr_t addr, uint32_t val) +static __inline void +SET_BITS(uintptr_t addr, uint32_t val) { - if (IS_32_ADDR(addr)) - { - if (val & ~0xff) - { - addbyte(0x81); /*OR [addr], val*/ - addbyte(0x0c); - addbyte(0x25); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x80); /*OR [addr], val*/ - addbyte(0x0c); - addbyte(0x25); - addlong(addr); - addbyte(val); - } + if (IS_32_ADDR(addr)) { + if (val & ~0xff) { + addbyte(0x81); /*OR [addr], val*/ + addbyte(0x0c); + addbyte(0x25); + addlong(addr); + addlong(val); + } else { + addbyte(0x80); /*OR [addr], val*/ + addbyte(0x0c); + addbyte(0x25); + addlong(addr); + addbyte(val); } - else - { - addbyte(0x48); /*MOV RAX, &addr*/ - addbyte(0xb8 | REG_EAX); - addquad(addr); - if (val & ~0xff) - { - addbyte(0x81); /*OR [RAX], val*/ - addbyte(0x08); - addlong(val); - } - else - { - addbyte(0x80); /*OR [RAX], val*/ - addbyte(0x08); - addbyte(val); - } + } else { + addbyte(0x48); /*MOV RAX, &addr*/ + addbyte(0xb8 | REG_EAX); + addquad(addr); + if (val & ~0xff) { + addbyte(0x81); /*OR [RAX], val*/ + addbyte(0x08); + addlong(val); + } else { + addbyte(0x80); /*OR [RAX], val*/ + addbyte(0x08); + addbyte(val); } + } } -static inline void CLEAR_BITS(uintptr_t addr, uint32_t val) +static __inline void +CLEAR_BITS(uintptr_t addr, uint32_t val) { - if (IS_32_ADDR(addr)) - { - if (val & ~0xff) - { - addbyte(0x81); /*AND [addr], val*/ - addbyte(0x24); - addbyte(0x25); - addlong(addr); - addlong(~val); - } - else - { - addbyte(0x80); /*AND [addr], val*/ - addbyte(0x24); - addbyte(0x25); - addlong(addr); - addbyte(~val); - } + if (IS_32_ADDR(addr)) { + if (val & ~0xff) { + addbyte(0x81); /*AND [addr], val*/ + addbyte(0x24); + addbyte(0x25); + addlong(addr); + addlong(~val); + } else { + addbyte(0x80); /*AND [addr], val*/ + addbyte(0x24); + addbyte(0x25); + addlong(addr); + addbyte(~val); } - else - { - addbyte(0x48); /*MOV RAX, &addr*/ - addbyte(0xb8 | REG_EAX); - addquad(addr); - if (val & ~0xff) - { - addbyte(0x81); /*AND [RAX], val*/ - addbyte(0x20); - addlong(~val); - } - else - { - addbyte(0x80); /*AND [RAX], val*/ - addbyte(0x20); - addbyte(~val); - } + } else { + addbyte(0x48); /*MOV RAX, &addr*/ + addbyte(0xb8 | REG_EAX); + addquad(addr); + if (val & ~0xff) { + addbyte(0x81); /*AND [RAX], val*/ + addbyte(0x20); + addlong(~val); + } else { + addbyte(0x80); /*AND [RAX], val*/ + addbyte(0x20); + addbyte(~val); } + } } #define LOAD_Q_REG_1 REG_EAX #define LOAD_Q_REG_2 REG_EDX -static inline void MMX_ENTER() +static __inline void +MMX_ENTER(void) { - if (codegen_mmx_entered) - return; + if (codegen_mmx_entered) + return; - if (IS_32_ADDR(&cr0)) - { - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x04); - addbyte(0x25); - addlong((uintptr_t)&cr0); - addbyte(0x0c); - } - else - { - addbyte(0x48); /*MOV RAX, &cr0*/ - addbyte(0xb8 | REG_EAX); - addquad((uint64_t)&cr0); - addbyte(0xf6); /*TEST [RAX], 0xc*/ - addbyte(0 | (REG_EAX << 3)); - addbyte(0x0c); - } - addbyte(0x74); /*JZ +*/ - addbyte(7+5+12+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC((uintptr_t)x86_int); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + if (IS_32_ADDR(&cr0)) { + addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0x04); + addbyte(0x25); + addlong((uintptr_t) &cr0); + addbyte(0x0c); + } else { + addbyte(0x48); /*MOV RAX, &cr0*/ + addbyte(0xb8 | REG_EAX); + addquad((uint64_t) &cr0); + addbyte(0xf6); /*TEST [RAX], 0xc*/ + addbyte(0 | (REG_EAX << 3)); + addbyte(0x0c); + } + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + 12 + 5); + addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(op_old_pc); + load_param_1_32(&codeblock[block_current], 7); + CALL_FUNC((uintptr_t) x86_int); + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0x31); /*XOR EAX, EAX*/ + addbyte(0xc0); + addbyte(0xc6); /*MOV ISMMX, 1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ismmx)); + addbyte(1); + addbyte(0x89); /*MOV TOP, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV tag, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x89); /*MOV tag+4, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[4])); - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xc6); /*MOV ISMMX, 1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ismmx)); - addbyte(1); - addbyte(0x89); /*MOV TOP, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV tag, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV tag+4, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[4])); - - codegen_mmx_entered = 1; + codegen_mmx_entered = 1; } extern int mmx_ebx_ecx_loaded; -static inline int LOAD_MMX_D(int guest_reg) +static __inline int +LOAD_MMX_D(int guest_reg) { - int host_reg = REG_EBX; + int host_reg = REG_EBX; - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x44 | (host_reg << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x8b); /*MOV EBX, reg*/ + addbyte(0x44 | (host_reg << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); - return host_reg; + return host_reg; } -static inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) +static __inline void +LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) { - int host_reg = REG_EBX; + int host_reg = REG_EBX; - if (host_reg & 8) - addbyte(0x4c); - else - addbyte(0x48); - addbyte(0x8b); /*MOV RBX, reg*/ - addbyte(0x44 | ((host_reg & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + if (host_reg & 8) + addbyte(0x4c); + else + addbyte(0x48); + addbyte(0x8b); /*MOV RBX, reg*/ + addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); - *host_reg1 = host_reg; + *host_reg1 = host_reg; } -static inline int LOAD_MMX_Q_MMX(int guest_reg) +static __inline int +LOAD_MMX_Q_MMX(int guest_reg) { - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = 100; + int dst_reg = find_host_xmm_reg(); + host_reg_xmm_mapping[dst_reg] = 100; - addbyte(0xf3); /*MOV XMMx, reg*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44 | ((dst_reg & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + addbyte(0xf3); /*MOV XMMx, reg*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44 | ((dst_reg & 7) << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); - return dst_reg; + return dst_reg; } -static inline int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) +static __inline int +LOAD_INT_TO_MMX(int src_reg1, int src_reg2) { - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = 100; + int dst_reg = find_host_xmm_reg(); + host_reg_xmm_mapping[dst_reg] = 100; - addbyte(0x66); /*MOVQ host_reg, src_reg1*/ - if (src_reg1 & 8) - addbyte(0x49); - else - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (dst_reg << 3) | (src_reg1 & 7)); + addbyte(0x66); /*MOVQ host_reg, src_reg1*/ + if (src_reg1 & 8) + addbyte(0x49); + else + addbyte(0x48); + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc0 | (dst_reg << 3) | (src_reg1 & 7)); - return dst_reg; + return dst_reg; } -static inline void STORE_MMX_LQ(int guest_reg, int host_reg1) +static __inline void +STORE_MMX_LQ(int guest_reg, int host_reg1) { - addbyte(0xC7); /*MOVL [reg],0*/ + addbyte(0xC7); /*MOVL [reg],0*/ + addbyte(0x44); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[1])); + addlong(0); + if (host_reg1 & 8) addbyte(0x44); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); - addlong(0); - if (host_reg1 & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x44 | ((host_reg1 & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x44 | ((host_reg1 & 7) << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); } -static inline void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) +static __inline void +STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) { - if (host_reg1 & 8) - addbyte(0x4c); - else - addbyte(0x48); - addbyte(0x89); /*MOV [reg],host_reg*/ - addbyte(0x44 | ((host_reg1 & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + if (host_reg1 & 8) + addbyte(0x4c); + else + addbyte(0x48); + addbyte(0x89); /*MOV [reg],host_reg*/ + addbyte(0x44 | ((host_reg1 & 7) << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); } -static inline void STORE_MMX_Q_MMX(int guest_reg, int host_reg) +static __inline void +STORE_MMX_Q_MMX(int guest_reg, int host_reg) { - addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44 | (host_reg << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44 | (host_reg << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); } -#define MMX_x86_OP(name, opcode) \ -static inline void MMX_ ## name(int dst_reg, int src_reg) \ -{ \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ -} +#define MMX_x86_OP(name, opcode) \ + static __inline void MMX_##name(int dst_reg, int src_reg) \ + { \ + addbyte(0x66); /*op dst_reg, src_reg*/ \ + addbyte(0x0f); \ + addbyte(opcode); \ + addbyte(0xc0 | (dst_reg << 3) | src_reg); \ + } -MMX_x86_OP(AND, 0xdb) -MMX_x86_OP(ANDN, 0xdf) -MMX_x86_OP(OR, 0xeb) -MMX_x86_OP(XOR, 0xef) +MMX_x86_OP(AND, 0xdb) + MMX_x86_OP(ANDN, 0xdf) + MMX_x86_OP(OR, 0xeb) + MMX_x86_OP(XOR, 0xef) -MMX_x86_OP(ADDB, 0xfc) -MMX_x86_OP(ADDW, 0xfd) -MMX_x86_OP(ADDD, 0xfe) -MMX_x86_OP(ADDSB, 0xec) -MMX_x86_OP(ADDSW, 0xed) -MMX_x86_OP(ADDUSB, 0xdc) -MMX_x86_OP(ADDUSW, 0xdd) + MMX_x86_OP(ADDB, 0xfc) + MMX_x86_OP(ADDW, 0xfd) + MMX_x86_OP(ADDD, 0xfe) + MMX_x86_OP(ADDSB, 0xec) + MMX_x86_OP(ADDSW, 0xed) + MMX_x86_OP(ADDUSB, 0xdc) + MMX_x86_OP(ADDUSW, 0xdd) -MMX_x86_OP(SUBB, 0xf8) -MMX_x86_OP(SUBW, 0xf9) -MMX_x86_OP(SUBD, 0xfa) -MMX_x86_OP(SUBSB, 0xe8) -MMX_x86_OP(SUBSW, 0xe9) -MMX_x86_OP(SUBUSB, 0xd8) -MMX_x86_OP(SUBUSW, 0xd9) + MMX_x86_OP(SUBB, 0xf8) + MMX_x86_OP(SUBW, 0xf9) + MMX_x86_OP(SUBD, 0xfa) + MMX_x86_OP(SUBSB, 0xe8) + MMX_x86_OP(SUBSW, 0xe9) + MMX_x86_OP(SUBUSB, 0xd8) + MMX_x86_OP(SUBUSW, 0xd9) -MMX_x86_OP(PUNPCKLBW, 0x60); + MMX_x86_OP(PUNPCKLBW, 0x60); MMX_x86_OP(PUNPCKLWD, 0x61); MMX_x86_OP(PUNPCKLDQ, 0x62); -MMX_x86_OP(PCMPGTB, 0x64); -MMX_x86_OP(PCMPGTW, 0x65); -MMX_x86_OP(PCMPGTD, 0x66); +MMX_x86_OP(PCMPGTB, 0x64); +MMX_x86_OP(PCMPGTW, 0x65); +MMX_x86_OP(PCMPGTD, 0x66); -MMX_x86_OP(PCMPEQB, 0x74); -MMX_x86_OP(PCMPEQW, 0x75); -MMX_x86_OP(PCMPEQD, 0x76); +MMX_x86_OP(PCMPEQB, 0x74); +MMX_x86_OP(PCMPEQW, 0x75); +MMX_x86_OP(PCMPEQD, 0x76); -MMX_x86_OP(PSRLW, 0xd1); -MMX_x86_OP(PSRLD, 0xd2); -MMX_x86_OP(PSRLQ, 0xd3); -MMX_x86_OP(PSRAW, 0xe1); -MMX_x86_OP(PSRAD, 0xe2); -MMX_x86_OP(PSLLW, 0xf1); -MMX_x86_OP(PSLLD, 0xf2); -MMX_x86_OP(PSLLQ, 0xf3); +MMX_x86_OP(PSRLW, 0xd1); +MMX_x86_OP(PSRLD, 0xd2); +MMX_x86_OP(PSRLQ, 0xd3); +MMX_x86_OP(PSRAW, 0xe1); +MMX_x86_OP(PSRAD, 0xe2); +MMX_x86_OP(PSLLW, 0xf1); +MMX_x86_OP(PSLLD, 0xf2); +MMX_x86_OP(PSLLQ, 0xf3); -MMX_x86_OP(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); +MMX_x86_OP(PMULLW, 0xd5); +MMX_x86_OP(PMULHW, 0xe5); MMX_x86_OP(PMADDWD, 0xf5); -static inline void MMX_PACKSSWB(int dst_reg, int src_reg) +static __inline void +MMX_PACKSSWB(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x63); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x63); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static inline void MMX_PACKUSWB(int dst_reg, int src_reg) +static __inline void +MMX_PACKUSWB(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static inline void MMX_PACKSSDW(int dst_reg, int src_reg) +static __inline void +MMX_PACKSSDW(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHBW(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHWD(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x61); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHDQ(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x62); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static inline void MMX_PSRLW_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static inline void MMX_PSRAW_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static inline void MMX_PSLLW_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } -static inline void MMX_PSRLD_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static inline void MMX_PSRAD_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static inline void MMX_PSLLD_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } -static inline void MMX_PSRLQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static inline void MMX_PSRAQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static inline void MMX_PSLLQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } - -static inline void SAVE_EA() +static __inline void +SAVE_EA(void) { - addbyte(0x89); /*MOV [ESP+0x24], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x24); + addbyte(0x89); /*MOV [ESP+0x24], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x24); } -static inline void LOAD_EA() +static __inline void +LOAD_EA(void) { - addbyte(0x8b); /*MOV EAX, [ESP+0x24]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x24); + addbyte(0x8b); /*MOV EAX, [ESP+0x24]*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x24); } #define MEM_CHECK_WRITE_B MEM_CHECK_WRITE -static inline void MEM_CHECK_WRITE(x86seg *seg) +static __inline void +MEM_CHECK_WRITE(x86seg *seg) { - uint8_t *jump1, *jump2, *jump3 = NULL; + uint8_t *jump1, *jump2, *jump3 = NULL; - CHECK_SEG_WRITE(seg); + CHECK_SEG_WRITE(seg); - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&cr0); - addbyte(0); - } - else - { - addbyte(0x48); /*MOV RDI, &cr0*/ - addbyte(0xbf); - addquad((uint64_t)&cr0); - addbyte(0x83); /*CMPL [RDI], 0*/ - addbyte(0x3f); - addbyte(0); - } - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - addbyte(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RCX, writelookup2*/ - addbyte(0xb9); - addquad((uint64_t)writelookup2); - addbyte(0x83); /*CMP [RCX+RDI*8], -1*/ - addbyte(0x3c); - addbyte(0xf9); - addbyte(-1); - } - addbyte(0x75); /*JNE +*/ - jump2 = &codeblock[block_current].data[block_pos]; - addbyte(0); - - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - /*slowpath:*/ - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - - - load_param_1_reg_32(REG_EDI); - load_param_2_32(&codeblock[block_current], 1); - - call(&codeblock[block_current], (uintptr_t)mmutranslatereal32); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - - LOAD_EA(); -} - -static inline void MEM_CHECK_WRITE_W(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; - int jump_pos; - - CHECK_SEG_WRITE(seg); - - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&cr0); - addbyte(0); - } - else - { - addbyte(0x48); /*MOV RDI, &cr0*/ - addbyte(0xbf); - addquad((uint64_t)&cr0); - addbyte(0x83); /*CMPL [RDI], 0*/ - addbyte(0x3f); - addbyte(0); - } - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - addbyte(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } - addbyte(0x8d); /*LEA ESI, 1[EDI]*/ - addbyte(0x77); - addbyte(0x01); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } - addbyte(0x89); /*MOV EBX, EDI*/ - addbyte(0xfb); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RAX, writelookup2*/ - addbyte(0xb8); - addquad((uint64_t)writelookup2); - addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ - addbyte(0x3c); - addbyte(0xf8); - addbyte(-1); - } - addbyte(0x74); /*JE +*/ - jump2 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ - addbyte(0x3c); - addbyte(0xf0); - addbyte(-1); - } - addbyte(0x75); /*JNE +*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - - /*slowpath:*/ - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; - jump_pos = block_pos; - load_param_1_reg_32(REG_EBX); - load_param_2_32(&codeblock[block_current], 1); - call(&codeblock[block_current], (uintptr_t)mmutranslatereal32); - addbyte(0x83); /*ADD EBX, 1*/ - addbyte(0xc3); - addbyte(1); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST $fff, EBX*/ - addbyte(0xc3); - addlong(0xfff); - addbyte(0x74); /*JNE slowpath*/ - addbyte(jump_pos - block_pos - 1); - - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - - LOAD_EA(); -} - -static inline void MEM_CHECK_WRITE_L(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; - int jump_pos; - - CHECK_SEG_WRITE(seg); - - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&cr0); - addbyte(0); - } - else - { - addbyte(0x48); /*MOV RDI, &cr0*/ - addbyte(0xbf); - addquad((uint64_t)&cr0); - addbyte(0x83); /*CMPL [RDI], 0*/ - addbyte(0x3f); - addbyte(0); - } - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - addbyte(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } - addbyte(0x8d); /*LEA ESI, 3[EDI]*/ - addbyte(0x77); - addbyte(0x03); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } - addbyte(0x89); /*MOV EBX, EDI*/ - addbyte(0xfb); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RAX, writelookup2*/ - addbyte(0xb8); - addquad((uint64_t)writelookup2); - addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ - addbyte(0x3c); - addbyte(0xf8); - addbyte(-1); - } - addbyte(0x74); /*JE slowpath*/ - jump2 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ - addbyte(0x3c); - addbyte(0xf0); - addbyte(-1); - } - addbyte(0x75); /*JNE +*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - - /*slowpath:*/ - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; - jump_pos = block_pos; - load_param_1_reg_32(REG_EBX); - load_param_2_32(&codeblock[block_current], 1); - call(&codeblock[block_current], (uintptr_t)mmutranslatereal32); - addbyte(0x83); /*ADD EBX, 3*/ - addbyte(0xc3); - addbyte(3); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST $ffc, EBX*/ - addbyte(0xc3); - addlong(0xffc); - addbyte(0x74); /*JE slowpath*/ - addbyte(jump_pos - block_pos - 1); - - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - - LOAD_EA(); -} - -static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ESI, [RSI]*/ + addbyte(0x36); + } + + /*seg = ESI, addr = EAX*/ + + if (IS_32_ADDR(&cr0)) { + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &cr0); + addbyte(0); + } else { + addbyte(0x48); /*MOV RDI, &cr0*/ + addbyte(0xbf); + addquad((uint64_t) &cr0); + addbyte(0x83); /*CMPL [RDI], 0*/ + addbyte(0x3f); + addbyte(0); + } + addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x8d); + addbyte(0x3c); + addbyte(0x30); + addbyte(0x79); /*JNS +*/ + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); + addbyte(0xfe); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmembl); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t) (uintptr_t) writelookup2); addbyte(-1); + } else { + addbyte(0x48); /*MOV RCX, writelookup2*/ + addbyte(0xb9); + addquad((uint64_t) writelookup2); + addbyte(0x83); /*CMP [RCX+RDI*8], -1*/ + addbyte(0x3c); + addbyte(0xf9); + addbyte(-1); + } + addbyte(0x75); /*JNE +*/ + jump2 = &codeblock[block_current].data[block_pos]; + addbyte(0); + + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + *jump3 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump3 - 1; + /*slowpath:*/ + addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x8d); + addbyte(0x3c); + addbyte(0x30); + + load_param_1_reg_32(REG_EDI); + load_param_2_32(&codeblock[block_current], 1); + + call(&codeblock[block_current], (uintptr_t) mmutranslatereal32); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong((uintptr_t) &codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t) (&codeblock[block_current].data[block_pos]) + 4)); + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + *jump2 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump2 - 1; + + LOAD_EA(); +} + +static __inline void +MEM_CHECK_WRITE_W(x86seg *seg) +{ + uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; + int jump_pos; + + CHECK_SEG_WRITE(seg); + + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOV ESI, seg->base*/ + addbyte(0x34); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ESI, [RSI]*/ + addbyte(0x36); + } + + /*seg = ESI, addr = EAX*/ + + if (IS_32_ADDR(&cr0)) { + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &cr0); + addbyte(0); + } else { + addbyte(0x48); /*MOV RDI, &cr0*/ + addbyte(0xbf); + addquad((uint64_t) &cr0); + addbyte(0x83); /*CMPL [RDI], 0*/ + addbyte(0x3f); + addbyte(0); + } + addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x8d); + addbyte(0x3c); + addbyte(0x30); + addbyte(0x79); /*JNS +*/ + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } + addbyte(0x8d); /*LEA ESI, 1[EDI]*/ + addbyte(0x77); + addbyte(0x01); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x66); /*MOV AX,[RDI+RSI]*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } + addbyte(0x89); /*MOV EBX, EDI*/ + addbyte(0xfb); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xee); + addbyte(12); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t) (uintptr_t) writelookup2); + addbyte(-1); + } else { + addbyte(0x48); /*MOV RAX, writelookup2*/ + addbyte(0xb8); + addquad((uint64_t) writelookup2); + addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ + addbyte(0x3c); + addbyte(0xf8); + addbyte(-1); + } + addbyte(0x74); /*JE +*/ + jump2 = &codeblock[block_current].data[block_pos]; + addbyte(0); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ + addbyte(0x3c); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + addbyte(-1); + } else { + addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ + addbyte(0x3c); + addbyte(0xf0); + addbyte(-1); + } + addbyte(0x75); /*JNE +*/ + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + + /*slowpath:*/ + *jump2 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump2 - 1; + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + *jump4 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump4 - 1; + jump_pos = block_pos; + load_param_1_reg_32(REG_EBX); + load_param_2_32(&codeblock[block_current], 1); + call(&codeblock[block_current], (uintptr_t) mmutranslatereal32); + addbyte(0x83); /*ADD EBX, 1*/ + addbyte(0xc3); + addbyte(1); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong((uintptr_t) &codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t) (&codeblock[block_current].data[block_pos]) + 4)); + /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ + addbyte(0xf7); /*TEST $fff, EBX*/ + addbyte(0xc3); + addlong(0xfff); + addbyte(0x74); /*JNE slowpath*/ + addbyte(jump_pos - block_pos - 1); + + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + *jump3 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump3 - 1; + + LOAD_EA(); +} + +static __inline void +MEM_CHECK_WRITE_L(x86seg *seg) +{ + uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; + int jump_pos; + + CHECK_SEG_WRITE(seg); + + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOV ESI, seg->base*/ + addbyte(0x34); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ESI, [RSI]*/ + addbyte(0x36); + } + + /*seg = ESI, addr = EAX*/ + + if (IS_32_ADDR(&cr0)) { + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &cr0); + addbyte(0); + } else { + addbyte(0x48); /*MOV RDI, &cr0*/ + addbyte(0xbf); + addquad((uint64_t) &cr0); + addbyte(0x83); /*CMPL [RDI], 0*/ + addbyte(0x3f); + addbyte(0); + } + addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x8d); + addbyte(0x3c); + addbyte(0x30); + addbyte(0x79); /*JNS +*/ + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } + addbyte(0x8d); /*LEA ESI, 3[EDI]*/ + addbyte(0x77); + addbyte(0x03); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } + addbyte(0x89); /*MOV EBX, EDI*/ + addbyte(0xfb); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xee); + addbyte(12); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t) (uintptr_t) writelookup2); + addbyte(-1); + } else { + addbyte(0x48); /*MOV RAX, writelookup2*/ + addbyte(0xb8); + addquad((uint64_t) writelookup2); + addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ + addbyte(0x3c); + addbyte(0xf8); + addbyte(-1); + } + addbyte(0x74); /*JE slowpath*/ + jump2 = &codeblock[block_current].data[block_pos]; + addbyte(0); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ + addbyte(0x3c); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + addbyte(-1); + } else { + addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ + addbyte(0x3c); + addbyte(0xf0); + addbyte(-1); + } + addbyte(0x75); /*JNE +*/ + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + + /*slowpath:*/ + *jump2 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump2 - 1; + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + *jump4 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump4 - 1; + jump_pos = block_pos; + load_param_1_reg_32(REG_EBX); + load_param_2_32(&codeblock[block_current], 1); + call(&codeblock[block_current], (uintptr_t) mmutranslatereal32); + addbyte(0x83); /*ADD EBX, 3*/ + addbyte(0xc3); + addbyte(3); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong((uintptr_t) &codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t) (&codeblock[block_current].data[block_pos]) + 4)); + /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ + addbyte(0xf7); /*TEST $ffc, EBX*/ + addbyte(0xc3); + addlong(0xffc); + addbyte(0x74); /*JE slowpath*/ + addbyte(jump_pos - block_pos - 1); + + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + *jump3 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump3 - 1; + + LOAD_EA(); +} + +static __inline int +MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); addbyte(0x8b); - addbyte(0x04); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 2); + addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmembl); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc1); + /*done:*/ + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} +static __inline int +MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 2); + addbyte(0x66); /*MOV AX,[RDI+RSI]*/ + addbyte(0x8b); + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemwl); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc1); + /*done:*/ + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} +static __inline int +MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 2); + addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemll); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc1); + /*done:*/ + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} + +static __inline void +MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) +{ + if (host_reg & 0x10) { + /*Handle high byte of register*/ + if (host_reg & 8) { + addbyte(0x45); /*MOVL R8, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3)); + } else { + addbyte(0x41); /*MOVL R8, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3)); + } + addbyte(0x66); /*SHR R8, 8*/ + addbyte(0x41); + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + host_reg = 8; + } + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL EBX, seg->base*/ + addbyte(0x1c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV EBX, [RSI]*/ + addbyte(0x1e); + } + addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x18); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 4 : 3) + 2); + if (host_reg & 8) { + addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x88); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemwl); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ - addbyte(0x04); + } else { + addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemll); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12); + } else { + addbyte(2 + 2 + 2 + 12); + } + /*slowpath:*/ + load_param_2_reg_32(host_reg); + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xc3); + load_param_1_reg_32(REG_EBX); + call_long((uintptr_t) writemembl); + /*done:*/ } - -static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if (host_reg & 0x10) - { - /*Handle high byte of register*/ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - addbyte(0x66); /*SHR R8, 8*/ - addbyte(0x41); - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - host_reg = 8; - } - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL EBX, seg->base*/ + addbyte(0x1c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV EBX, [RSI]*/ + addbyte(0x1e); + } + addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x18); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x88); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12); - } else { - addbyte(2+2+2+12); - } - /*slowpath:*/ - load_param_2_reg_32(host_reg); - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xc3); - load_param_1_reg_32(REG_EBX); - call_long((uintptr_t)writemembl); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); - if (host_reg & 8) - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12); - } else { - addbyte(2+2+2+12); - } - /*slowpath:*/ - load_param_2_reg_32(host_reg); - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xc3); - load_param_1_reg_32(REG_EBX); - call_long((uintptr_t)writememwl); - /*done:*/ + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + ((host_reg & 8) ? 5 : 4) + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 5 : 4) + 2); + if (host_reg & 8) { + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12); + } else { + addbyte(2 + 2 + 2 + 12); + } + /*slowpath:*/ + load_param_2_reg_32(host_reg); + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xc3); + load_param_1_reg_32(REG_EBX); + call_long((uintptr_t) writememwl); + /*done:*/ } -static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL EBX, seg->base*/ + addbyte(0x1c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV EBX, [RSI]*/ + addbyte(0x1e); + } + addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x18); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 4:3)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x89); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12); - } else { - addbyte(2+2+2+12); - } - /*slowpath:*/ - load_param_2_reg_32(host_reg); - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xc3); - load_param_1_reg_32(REG_EBX); - call_long((uintptr_t)writememll); - /*done:*/ + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + ((host_reg & 8) ? 4 : 3) + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 4 : 3) + 2); + if (host_reg & 8) { + addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x89); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12); + } else { + addbyte(2 + 2 + 2 + 12); + } + /*slowpath:*/ + load_param_2_reg_32(host_reg); + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xc3); + load_param_1_reg_32(REG_EBX); + call_long((uintptr_t) writememll); + /*done:*/ } -static inline void LOAD_SEG(int host_reg, void *seg) +static __inline void +LOAD_SEG(int host_reg, void *seg) { - load_param_2_64(&codeblock[block_current], (uint64_t)seg); - load_param_1_reg_32(host_reg); - CALL_FUNC((uintptr_t)loadseg); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + load_param_2_64(&codeblock[block_current], (uint64_t) seg); + load_param_1_reg_32(host_reg); + CALL_FUNC((uintptr_t) loadseg); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h index 35bdeb5ff..80e081220 100644 --- a/src/codegen/codegen_ops_x86.h +++ b/src/codegen/codegen_ops_x86.h @@ -4,46 +4,46 @@ ESI, EDI - work registers EBP - points at emulated register array */ -#define HOST_REG_START 1 -#define HOST_REG_END 4 +#define HOST_REG_START 1 +#define HOST_REG_END 4 #define HOST_REG_XMM_START 0 -#define HOST_REG_XMM_END 7 -static inline int find_host_reg() +#define HOST_REG_XMM_END 7 +static __inline int +find_host_reg(void) { - int c; - for (c = HOST_REG_START; c < HOST_REG_END; c++) - { - if (host_reg_mapping[c] == -1) - break; - } + int c; + for (c = HOST_REG_START; c < HOST_REG_END; c++) { + if (host_reg_mapping[c] == -1) + break; + } - if (c == NR_HOST_REGS) - fatal("Out of host regs!\n"); - return c; + if (c == NR_HOST_REGS) + fatal("Out of host regs!\n"); + return c; } -static inline int find_host_xmm_reg() +static __inline int +find_host_xmm_reg(void) { - int c; - for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) - { - if (host_reg_xmm_mapping[c] == -1) - break; - } + int c; + for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) { + if (host_reg_xmm_mapping[c] == -1) + break; + } - if (c == HOST_REG_XMM_END) - fatal("Out of host XMM regs!\n"); - return c; + if (c == HOST_REG_XMM_END) + fatal("Out of host XMM regs!\n"); + return c; } #if 0 -static inline void STORE_IMM_ADDR_B(uintptr_t addr, uint8_t val) +static __inline void STORE_IMM_ADDR_B(uintptr_t addr, uint8_t val) { addbyte(0xC6); /*MOVB [addr],val*/ addbyte(0x05); addlong(addr); addbyte(val); } -static inline void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) +static __inline void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) { addbyte(0x66); /*MOVW [addr],val*/ addbyte(0xC7); @@ -52,2637 +52,2572 @@ static inline void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) addword(val); } #endif -static inline void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte(addr - (uint32_t)&cpu_state - 128); - addlong(val); - } - else - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x05); - addlong(addr); - addlong(val); - } -} - -static inline void STORE_IMM_REG_B(int reg, uint8_t val) -{ - addbyte(0xC6); /*MOVB [addr],val*/ - addbyte(0x45); - if (reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); - addbyte(val); -} -static inline void STORE_IMM_REG_W(int reg, uint16_t val) -{ - addbyte(0x66); /*MOVW [addr],val*/ - addbyte(0xC7); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); - addword(val); -} -static inline void STORE_IMM_REG_L(int reg, uint32_t val) +static __inline void +STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) { + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { addbyte(0xC7); /*MOVL [addr],val*/ addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].l)); + addbyte(addr - (uint32_t) &cpu_state - 128); addlong(val); + } else { + addbyte(0xC7); /*MOVL [addr],val*/ + addbyte(0x05); + addlong(addr); + addlong(val); + } } -static inline int LOAD_REG_B(int reg) +static __inline void +STORE_IMM_REG_B(int reg, uint8_t val) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x0f); /*MOVZX B[reg],host_reg*/ - addbyte(0xb6); - addbyte(0x45 | (host_reg << 3)); - if (reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); - - return host_reg; + addbyte(0xC6); /*MOVB [addr],val*/ + addbyte(0x45); + if (reg & 4) + addbyte((uint8_t) cpu_state_offset(regs[reg & 3].b.h)); + else + addbyte((uint8_t) cpu_state_offset(regs[reg & 3].b.l)); + addbyte(val); } -static inline int LOAD_REG_W(int reg) +static __inline void +STORE_IMM_REG_W(int reg, uint16_t val) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x0f); /*MOVZX W[reg],host_reg*/ - addbyte(0xb7); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); - - return host_reg; + addbyte(0x66); /*MOVW [addr],val*/ + addbyte(0xC7); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[reg & 7].w)); + addword(val); } -static inline int LOAD_REG_L(int reg) +static __inline void +STORE_IMM_REG_L(int reg, uint32_t val) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].l)); - - return host_reg; + addbyte(0xC7); /*MOVL [addr],val*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[reg & 7].l)); + addlong(val); } -static inline int LOAD_VAR_W(uintptr_t addr) +static __inline int +LOAD_REG_B(int reg) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = reg; - addbyte(0x66); /*MOVL host_reg,[reg]*/ - addbyte(0x8b); - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); + addbyte(0x0f); /*MOVZX B[reg],host_reg*/ + addbyte(0xb6); + addbyte(0x45 | (host_reg << 3)); + if (reg & 4) + addbyte((uint8_t) cpu_state_offset(regs[reg & 3].b.h)); + else + addbyte((uint8_t) cpu_state_offset(regs[reg & 3].b.l)); - return host_reg; + return host_reg; } -static inline int LOAD_VAR_WL(uintptr_t addr) +static __inline int +LOAD_REG_W(int reg) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = reg; - addbyte(0x0f); /*MOVZX host_reg, [addr]*/ - addbyte(0xb7); - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); + addbyte(0x0f); /*MOVZX W[reg],host_reg*/ + addbyte(0xb7); + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[reg & 7].w)); - return host_reg; + return host_reg; } -static inline int LOAD_VAR_L(uintptr_t addr) +static __inline int +LOAD_REG_L(int reg) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = reg; - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); + addbyte(0x8b); /*MOVL host_reg,[reg]*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[reg & 7].l)); - return host_reg; + return host_reg; } -static inline int LOAD_REG_IMM(uint32_t imm) +static __inline int +LOAD_VAR_W(uintptr_t addr) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 0; - addbyte(0xc7); /*MOVL host_reg, imm*/ - addbyte(0xc0 | host_reg); - addlong(imm); + addbyte(0x66); /*MOVL host_reg,[reg]*/ + addbyte(0x8b); + addbyte(0x05 | (host_reg << 3)); + addlong((uint32_t) addr); - return host_reg; + return host_reg; +} +static __inline int +LOAD_VAR_WL(uintptr_t addr) +{ + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 0; + + addbyte(0x0f); /*MOVZX host_reg, [addr]*/ + addbyte(0xb7); + addbyte(0x05 | (host_reg << 3)); + addlong((uint32_t) addr); + + return host_reg; +} +static __inline int +LOAD_VAR_L(uintptr_t addr) +{ + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 0; + + addbyte(0x8b); /*MOVL host_reg,[reg]*/ + addbyte(0x05 | (host_reg << 3)); + addlong((uint32_t) addr); + + return host_reg; } -static inline int LOAD_HOST_REG(int host_reg) +static __inline int +LOAD_REG_IMM(uint32_t imm) { - int new_host_reg = find_host_reg(); - host_reg_mapping[new_host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 0; - addbyte(0x89); /*MOV new_host_reg, host_reg*/ - addbyte(0xc0 | (host_reg << 3) | new_host_reg); + addbyte(0xc7); /*MOVL host_reg, imm*/ + addbyte(0xc0 | host_reg); + addlong(imm); - return new_host_reg; + return host_reg; } -static inline void STORE_REG_B_RELEASE(int host_reg) +static __inline int +LOAD_HOST_REG(int host_reg) { - addbyte(0x88); /*MOVB [reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - if (host_reg_mapping[host_reg] & 4) - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.l)); - host_reg_mapping[host_reg] = -1; + int new_host_reg = find_host_reg(); + host_reg_mapping[new_host_reg] = 0; + + addbyte(0x89); /*MOV new_host_reg, host_reg*/ + addbyte(0xc0 | (host_reg << 3) | new_host_reg); + + return new_host_reg; } -static inline void STORE_REG_W_RELEASE(int host_reg) + +static __inline void +STORE_REG_B_RELEASE(int host_reg) { - addbyte(0x66); /*MOVW [reg],host_reg*/ + addbyte(0x88); /*MOVB [reg],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + if (host_reg_mapping[host_reg] & 4) + addbyte((uint8_t) cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.h)); + else + addbyte((uint8_t) cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.l)); + host_reg_mapping[host_reg] = -1; +} +static __inline void +STORE_REG_W_RELEASE(int host_reg) +{ + addbyte(0x66); /*MOVW [reg],host_reg*/ + addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[host_reg_mapping[host_reg]].w)); + host_reg_mapping[host_reg] = -1; +} +static __inline void +STORE_REG_L_RELEASE(int host_reg) +{ + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[host_reg_mapping[host_reg]].l)); + host_reg_mapping[host_reg] = -1; +} + +static __inline void +STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) +{ + addbyte(0x88); /*MOVB [guest_reg],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + if (guest_reg & 4) + addbyte((uint8_t) cpu_state_offset(regs[guest_reg & 3].b.h)); + else + addbyte((uint8_t) cpu_state_offset(regs[guest_reg & 3].b.l)); + host_reg_mapping[host_reg] = -1; +} +static __inline void +STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) +{ + addbyte(0x66); /*MOVW [guest_reg],host_reg*/ + addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[guest_reg & 7].w)); + host_reg_mapping[host_reg] = -1; +} +static __inline void +STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) +{ + addbyte(0x89); /*MOVL [guest_reg],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[guest_reg & 7].l)); + host_reg_mapping[host_reg] = -1; +} + +static __inline void +RELEASE_REG(int host_reg) +{ + host_reg_mapping[host_reg] = -1; +} + +static __inline void +STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) +{ + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x66); /*MOVW [addr],host_reg*/ addbyte(0x89); addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].w)); - host_reg_mapping[host_reg] = -1; + addbyte((uint32_t) addr - (uint32_t) &cpu_state - 128); + } else { + addbyte(0x66); /*MOVL [reg],host_reg*/ + addbyte(0x89); + addbyte(0x05 | (host_reg << 3)); + addlong(addr); + } } -static inline void STORE_REG_L_RELEASE(int host_reg) +static __inline void +STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) { + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x89); /*MOVL [addr],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint32_t) addr - (uint32_t) &cpu_state - 128); + } else { addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].l)); - host_reg_mapping[host_reg] = -1; -} - -static inline void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) -{ - addbyte(0x88); /*MOVB [guest_reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - if (guest_reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.l)); - host_reg_mapping[host_reg] = -1; -} -static inline void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) -{ - addbyte(0x66); /*MOVW [guest_reg],host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 7].w)); - host_reg_mapping[host_reg] = -1; -} -static inline void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) -{ - addbyte(0x89); /*MOVL [guest_reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 7].l)); - host_reg_mapping[host_reg] = -1; -} - -static inline void RELEASE_REG(int host_reg) -{ - host_reg_mapping[host_reg] = -1; -} - -static inline void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x66); /*MOVW [addr],host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); - } - else - { - addbyte(0x66); /*MOVL [reg],host_reg*/ - addbyte(0x89); - addbyte(0x05 | (host_reg << 3)); - addlong(addr); - } -} -static inline void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOVL [addr],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); - } - else - { - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x05 | (host_reg << 3)); - addlong(addr); - } + addbyte(0x05 | (host_reg << 3)); + addlong(addr); + } } #define STORE_HOST_REG_ADDR_BL STORE_HOST_REG_ADDR #define STORE_HOST_REG_ADDR_WL STORE_HOST_REG_ADDR -static inline void ADD_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_B(int dst_reg, int src_reg) { - addbyte(0x00); /*ADDB dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x00); /*ADDB dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static inline void ADD_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_W(int dst_reg, int src_reg) { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x01); + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static inline void ADD_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x01); /*ADDL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x01); /*ADDL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static inline void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline void +ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) { - addbyte(0x80); /*ADDB host_reg, imm*/ + addbyte(0x80); /*ADDB host_reg, imm*/ + addbyte(0xC0 | host_reg); + addbyte(imm); +} +static __inline void +ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +{ + if (imm < 0x80 || imm >= 0xff80) { + addbyte(0x66); /*ADDW host_reg, imm*/ + addbyte(0x83); addbyte(0xC0 | host_reg); - addbyte(imm); + addbyte(imm & 0xff); + } else { + addbyte(0x66); /*ADDW host_reg, imm*/ + addbyte(0x81); + addbyte(0xC0 | host_reg); + addword(imm); + } } -static inline void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static __inline void +ADD_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (imm < 0x80 || imm >= 0xff80) - { - addbyte(0x66); /*ADDW host_reg, imm*/ - addbyte(0x83); - addbyte(0xC0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x66); /*ADDW host_reg, imm*/ - addbyte(0x81); - addbyte(0xC0 | host_reg); - addword(imm); - } -} -static inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ADDL host_reg, imm*/ - addbyte(0xC0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ADDL host_reg, imm*/ - addbyte(0xC0 | host_reg); - addlong(imm); - } + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*ADDL host_reg, imm*/ + addbyte(0xC0 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x81); /*ADDL host_reg, imm*/ + addbyte(0xC0 | host_reg); + addlong(imm); + } } #define AND_HOST_REG_B AND_HOST_REG_L #define AND_HOST_REG_W AND_HOST_REG_L -static inline void AND_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +AND_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x21); /*ANDL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x21); /*ANDL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline void +AND_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ANDL host_reg, imm*/ - addbyte(0xE0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xE0 | host_reg); - addlong(imm); - } + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*ANDL host_reg, imm*/ + addbyte(0xE0 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x81); /*ANDL host_reg, imm*/ + addbyte(0xE0 | host_reg); + addlong(imm); + } } -static inline int TEST_HOST_REG_B(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_B(int dst_reg, int src_reg) { - AND_HOST_REG_B(dst_reg, src_reg); + AND_HOST_REG_B(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static inline int TEST_HOST_REG_W(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_W(int dst_reg, int src_reg) { - AND_HOST_REG_W(dst_reg, src_reg); + AND_HOST_REG_W(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static inline int TEST_HOST_REG_L(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_L(int dst_reg, int src_reg) { - AND_HOST_REG_L(dst_reg, src_reg); + AND_HOST_REG_L(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline int +TEST_HOST_REG_IMM(int host_reg, uint32_t imm) { - AND_HOST_REG_IMM(host_reg, imm); + AND_HOST_REG_IMM(host_reg, imm); - return host_reg; + return host_reg; } #define OR_HOST_REG_B OR_HOST_REG_L #define OR_HOST_REG_W OR_HOST_REG_L -static inline void OR_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +OR_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x09); /*ORL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x09); /*ORL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline void +OR_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ORL host_reg, imm*/ - addbyte(0xC8 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xC8 | host_reg); - addlong(imm); - } + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*ORL host_reg, imm*/ + addbyte(0xC8 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x81); /*ORL host_reg, imm*/ + addbyte(0xC8 | host_reg); + addlong(imm); + } } -static inline void NEG_HOST_REG_B(int reg) +static __inline void +NEG_HOST_REG_B(int reg) { - addbyte(0xf6); - addbyte(0xd8 | reg); + addbyte(0xf6); + addbyte(0xd8 | reg); } -static inline void NEG_HOST_REG_W(int reg) +static __inline void +NEG_HOST_REG_W(int reg) { - addbyte(0x66); - addbyte(0xf7); - addbyte(0xd8 | reg); + addbyte(0x66); + addbyte(0xf7); + addbyte(0xd8 | reg); } -static inline void NEG_HOST_REG_L(int reg) +static __inline void +NEG_HOST_REG_L(int reg) { - addbyte(0xf7); - addbyte(0xd8 | reg); + addbyte(0xf7); + addbyte(0xd8 | reg); } -static inline void SUB_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +SUB_HOST_REG_B(int dst_reg, int src_reg) { - addbyte(0x28); /*SUBB dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x28); /*SUBB dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static inline void SUB_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +SUB_HOST_REG_W(int dst_reg, int src_reg) { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static inline void SUB_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +SUB_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x29); /*SUBL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x29); /*SUBL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static inline void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline void +SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) { - addbyte(0x80); /*SUBB host_reg, imm*/ + addbyte(0x80); /*SUBB host_reg, imm*/ + addbyte(0xE8 | host_reg); + addbyte(imm); +} +static __inline void +SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) +{ + if (imm < 0x80 || imm >= 0xff80) { + addbyte(0x66); /*SUBW host_reg, imm*/ + addbyte(0x83); + addbyte(0xE8 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x66); /*SUBW host_reg, imm*/ + addbyte(0x81); + addbyte(0xE8 | host_reg); + addword(imm); + } +} +static __inline void +SUB_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*SUBL host_reg, imm*/ addbyte(0xE8 | host_reg); addbyte(imm); -} -static inline void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (imm < 0x80 || imm >= 0xff80) - { - addbyte(0x66); /*SUBW host_reg, imm*/ - addbyte(0x83); - addbyte(0xE8 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x66); /*SUBW host_reg, imm*/ - addbyte(0x81); - addbyte(0xE8 | host_reg); - addword(imm); - } -} -static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*SUBL host_reg, imm*/ - addbyte(0xE8 | host_reg); - addbyte(imm); - } - else - { - addbyte(0x81); /*SUBL host_reg, imm*/ - addbyte(0xE8 | host_reg); - addlong(imm); - } + } else { + addbyte(0x81); /*SUBL host_reg, imm*/ + addbyte(0xE8 | host_reg); + addlong(imm); + } } -static inline void INC_HOST_REG_W(int host_reg) +static __inline void +INC_HOST_REG_W(int host_reg) { - addbyte(0x66); /*INCW host_reg*/ - addbyte(0x40 | host_reg); + addbyte(0x66); /*INCW host_reg*/ + addbyte(0x40 | host_reg); } -static inline void INC_HOST_REG(int host_reg) +static __inline void +INC_HOST_REG(int host_reg) { - addbyte(0x40 | host_reg); /*DECL host_reg*/ + addbyte(0x40 | host_reg); /*DECL host_reg*/ } -static inline void DEC_HOST_REG_W(int host_reg) +static __inline void +DEC_HOST_REG_W(int host_reg) { - addbyte(0x66); /*DECW host_reg*/ - addbyte(0x48 | host_reg); + addbyte(0x66); /*DECW host_reg*/ + addbyte(0x48 | host_reg); } -static inline void DEC_HOST_REG(int host_reg) +static __inline void +DEC_HOST_REG(int host_reg) { - addbyte(0x48 | host_reg); /*DECL host_reg*/ + addbyte(0x48 | host_reg); /*DECL host_reg*/ } -static inline int CMP_HOST_REG_B(int dst_reg, int src_reg) +static __inline int +CMP_HOST_REG_B(int dst_reg, int src_reg) { - SUB_HOST_REG_B(dst_reg, src_reg); + SUB_HOST_REG_B(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static inline int CMP_HOST_REG_W(int dst_reg, int src_reg) +static __inline int +CMP_HOST_REG_W(int dst_reg, int src_reg) { - SUB_HOST_REG_W(dst_reg, src_reg); + SUB_HOST_REG_W(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static inline int CMP_HOST_REG_L(int dst_reg, int src_reg) +static __inline int +CMP_HOST_REG_L(int dst_reg, int src_reg) { - SUB_HOST_REG_L(dst_reg, src_reg); + SUB_HOST_REG_L(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline int +CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) { - SUB_HOST_REG_IMM_B(host_reg, imm); + SUB_HOST_REG_IMM_B(host_reg, imm); - return host_reg; + return host_reg; } -static inline int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static __inline int +CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) { - SUB_HOST_REG_IMM_W(host_reg, imm); + SUB_HOST_REG_IMM_W(host_reg, imm); - return host_reg; + return host_reg; } -static inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) +static __inline int +CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) { - SUB_HOST_REG_IMM(host_reg, imm); + SUB_HOST_REG_IMM(host_reg, imm); - return host_reg; + return host_reg; } #define XOR_HOST_REG_B XOR_HOST_REG_L #define XOR_HOST_REG_W XOR_HOST_REG_L -static inline void XOR_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +XOR_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x31); /*XORL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x31); /*XORL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline void +XOR_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*XORL host_reg, imm*/ - addbyte(0xF0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*XORL host_reg, imm*/ - addbyte(0xF0 | host_reg); - addlong(imm); - } + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*XORL host_reg, imm*/ + addbyte(0xF0 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x81); /*XORL host_reg, imm*/ + addbyte(0xF0 | host_reg); + addlong(imm); + } } -static inline void CALL_FUNC(uintptr_t dest) +static __inline void +CALL_FUNC(uintptr_t dest) { - addbyte(0xE8); /*CALL*/ - addlong(((uintptr_t)dest - (uintptr_t)(&codeblock[block_current].data[block_pos + 4]))); + addbyte(0xE8); /*CALL*/ + addlong(((uintptr_t) dest - (uintptr_t) (&codeblock[block_current].data[block_pos + 4]))); } -static inline void SHL_B_IMM(int reg, int count) +static __inline void +SHL_B_IMM(int reg, int count) { - addbyte(0xc0); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(count); + addbyte(0xc0); /*SHL reg, count*/ + addbyte(0xc0 | reg | 0x20); + addbyte(count); } -static inline void SHL_W_IMM(int reg, int count) +static __inline void +SHL_W_IMM(int reg, int count) { - addbyte(0x66); /*SHL reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x20); - addbyte(count); + addbyte(0x66); /*SHL reg, count*/ + addbyte(0xc1); + addbyte(0xc0 | reg | 0x20); + addbyte(count); } -static inline void SHL_L_IMM(int reg, int count) +static __inline void +SHL_L_IMM(int reg, int count) { - addbyte(0xc1); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(count); + addbyte(0xc1); /*SHL reg, count*/ + addbyte(0xc0 | reg | 0x20); + addbyte(count); } -static inline void SHR_B_IMM(int reg, int count) +static __inline void +SHR_B_IMM(int reg, int count) { - addbyte(0xc0); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(count); + addbyte(0xc0); /*SHR reg, count*/ + addbyte(0xc0 | reg | 0x28); + addbyte(count); } -static inline void SHR_W_IMM(int reg, int count) +static __inline void +SHR_W_IMM(int reg, int count) { - addbyte(0x66); /*SHR reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x28); - addbyte(count); + addbyte(0x66); /*SHR reg, count*/ + addbyte(0xc1); + addbyte(0xc0 | reg | 0x28); + addbyte(count); } -static inline void SHR_L_IMM(int reg, int count) +static __inline void +SHR_L_IMM(int reg, int count) { - addbyte(0xc1); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(count); + addbyte(0xc1); /*SHR reg, count*/ + addbyte(0xc0 | reg | 0x28); + addbyte(count); } -static inline void SAR_B_IMM(int reg, int count) +static __inline void +SAR_B_IMM(int reg, int count) { - addbyte(0xc0); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(count); + addbyte(0xc0); /*SAR reg, count*/ + addbyte(0xc0 | reg | 0x38); + addbyte(count); } -static inline void SAR_W_IMM(int reg, int count) +static __inline void +SAR_W_IMM(int reg, int count) { - addbyte(0x66); /*SAR reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x38); - addbyte(count); + addbyte(0x66); /*SAR reg, count*/ + addbyte(0xc1); + addbyte(0xc0 | reg | 0x38); + addbyte(count); } -static inline void SAR_L_IMM(int reg, int count) +static __inline void +SAR_L_IMM(int reg, int count) { - addbyte(0xc1); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(count); + addbyte(0xc1); /*SAR reg, count*/ + addbyte(0xc0 | reg | 0x38); + addbyte(count); } - -static inline void CHECK_SEG_READ(x86seg *seg) +static __inline void +CHECK_SEG_READ(x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x05|0x38); - addlong((uint32_t)&seg->base); - addbyte(-1); - addbyte(0x0f); - addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + addbyte(0x83); /*CMP seg->base, -1*/ + addbyte(0x05 | 0x38); + addlong((uint32_t) &seg->base); + addbyte(-1); + addbyte(0x0f); + addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - seg->checked = 1; + seg->checked = 1; } -static inline void CHECK_SEG_WRITE(x86seg *seg) +static __inline void +CHECK_SEG_WRITE(x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x05|0x38); - addlong((uint32_t)&seg->base); - addbyte(-1); - addbyte(0x0f); - addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + addbyte(0x83); /*CMP seg->base, -1*/ + addbyte(0x05 | 0x38); + addlong((uint32_t) &seg->base); + addbyte(-1); + addbyte(0x0f); + addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - seg->checked = 1; + seg->checked = 1; } -static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) +static __inline void +CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + return; - addbyte(0x3b); /*CMP EAX, seg->limit_low*/ - addbyte(0x05); - addlong((uint32_t)&seg->limit_low); - addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ - addbyte(0x82); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - if (end_offset) - { - addbyte(0x83); /*ADD EAX, end_offset*/ - addbyte(0xc0); - addbyte(end_offset); - addbyte(0x3b); /*CMP EAX, seg->limit_high*/ - addbyte(0x05); - addlong((uint32_t)&seg->limit_high); - addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ - addbyte(0x87); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - addbyte(0x83); /*SUB EAX, end_offset*/ - addbyte(0xe8); - addbyte(end_offset); - } -} - -static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ - addlong(mem_load_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/ - addlong(mem_load_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ - addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0x83); /*ADD EAX, offset*/ + addbyte(0x3b); /*CMP EAX, seg->limit_low*/ + addbyte(0x05); + addlong((uint32_t) &seg->limit_low); + addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ + addbyte(0x82); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + if (end_offset) { + addbyte(0x83); /*ADD EAX, end_offset*/ addbyte(0xc0); - addbyte(offset); - addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ - addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/ - addlong(mem_load_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ - addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - - host_reg_mapping[0] = 8; -} -static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/ - addlong(mem_load_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; + addbyte(end_offset); + addbyte(0x3b); /*CMP EAX, seg->limit_high*/ + addbyte(0x05); + addlong((uint32_t) &seg->limit_high); + addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ + addbyte(0x87); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + addbyte(0x83); /*SUB EAX, end_offset*/ + addbyte(0xe8); + addbyte(end_offset); + } } -static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) +static __inline void +MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ - addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ + addlong(mem_load_addr_ea_b - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); - host_reg_mapping[0] = 8; + host_reg_mapping[0] = 8; +} +static __inline int +MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/ + addlong(mem_load_addr_ea_b_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} +static __inline void +MEM_LOAD_ADDR_EA_W(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ + addlong(mem_load_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[0] = 8; +} +static __inline void +MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0x83); /*ADD EAX, offset*/ + addbyte(0xc0); + addbyte(offset); + addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ + addlong(mem_load_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[0] = 8; +} +static __inline int +MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/ + addlong(mem_load_addr_ea_w_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} +static __inline void +MEM_LOAD_ADDR_EA_L(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ + addlong(mem_load_addr_ea_l - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[0] = 8; +} +static __inline int +MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/ + addlong(mem_load_addr_ea_l_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; } -static inline void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) +static __inline void +MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_B(seg); -} -static inline void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_W(seg); -} -static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_L(seg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ + addlong(mem_load_addr_ea_q - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[0] = 8; } -static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) +static __inline void +MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_b*/ - addlong(mem_store_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_B(seg); } -static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) +static __inline void +MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_b_no_abrt*/ - addlong(mem_store_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_W(seg); } -static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) +static __inline void +MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_w*/ - addlong(mem_store_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_w_no_abrt*/ - addlong(mem_store_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_l*/ - addlong(mem_store_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_l_no_abrt*/ - addlong(mem_store_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) -{ - if (host_reg != REG_EBX) - { - addbyte(0x89); /*MOV EBX, host_reg*/ - addbyte(0xc0 | REG_EBX | (host_reg << 3)); - } - if (host_reg2 != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg2*/ - addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); - } - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ - addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_L(seg); } -static inline void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_B(seg, host_reg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_b*/ + addlong(mem_store_addr_ea_b - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); } -static inline void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_L(seg, host_reg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_b_no_abrt*/ + addlong(mem_store_addr_ea_b_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); } -static inline void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_W(seg, host_reg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_w*/ + addlong(mem_store_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +} +static __inline void +MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_w_no_abrt*/ + addlong(mem_store_addr_ea_w_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +} +static __inline void +MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_l*/ + addlong(mem_store_addr_ea_l - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +} +static __inline void +MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_l_no_abrt*/ + addlong(mem_store_addr_ea_l_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +} +static __inline void +MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) +{ + if (host_reg != REG_EBX) { + addbyte(0x89); /*MOV EBX, host_reg*/ + addbyte(0xc0 | REG_EBX | (host_reg << 3)); + } + if (host_reg2 != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg2*/ + addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); + } + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ + addlong(mem_store_addr_ea_q - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); } - -static inline x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +static __inline void +MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) { - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - if (!mod && rm == 6) - { + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_B(seg, host_reg); +} +static __inline void +MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_L(seg, host_reg); +} +static __inline void +MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_W(seg, host_reg); +} + +static __inline x86seg * +FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +{ + int mod = (fetchdat >> 6) & 3; + int rm = fetchdat & 7; + if (!mod && rm == 6) { + addbyte(0xb8); /*MOVL EAX, imm16*/ + addlong((fetchdat >> 8) & 0xffff); + (*op_pc) += 2; + } else { + switch (mod) { + case 0: + addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ + addlong((uint32_t) mod1add[0][rm]); + if (mod1add[1][rm] != &zero) { + addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][rm]); + } + break; + case 1: + addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ + addlong((uint32_t) mod1add[0][rm]); + addbyte(0x83); /*ADDL EAX, imm8*/ + addbyte(0xc0 | REG_EAX); + addbyte((int8_t) (rmdat >> 8)); + if (mod1add[1][rm] != &zero) { + addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][rm]); + } + (*op_pc)++; + break; + case 2: addbyte(0xb8); /*MOVL EAX, imm16*/ addlong((fetchdat >> 8) & 0xffff); + addbyte(0x03); /*ADDL EAX, *mod1add[0][rm]*/ + addbyte(0x05); + addlong((uint32_t) mod1add[0][rm]); + if (mod1add[1][rm] != &zero) { + addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][rm]); + } (*op_pc) += 2; + break; } - else - { - switch (mod) - { - case 0: - addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ - addlong((uint32_t)mod1add[0][rm]); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - break; - case 1: - addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ - addlong((uint32_t)mod1add[0][rm]); - addbyte(0x83); /*ADDL EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(rmdat >> 8)); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - (*op_pc)++; - break; - case 2: - addbyte(0xb8); /*MOVL EAX, imm16*/ - addlong((fetchdat >> 8) & 0xffff); - addbyte(0x03); /*ADDL EAX, *mod1add[0][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][rm]); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - (*op_pc) += 2; - break; - } - addbyte(0x25); /*ANDL EAX, 0xffff*/ - addlong(0xffff); + addbyte(0x25); /*ANDL EAX, 0xffff*/ + addlong(0xffff); - if (mod1seg[rm] == &ss && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - } - return op_ea_seg; + if (mod1seg[rm] == &ss && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } + return op_ea_seg; } -static inline x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +static __inline x86seg * +FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { - uint32_t new_eaaddr; - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; + uint32_t new_eaaddr; + int mod = (fetchdat >> 6) & 3; + int rm = fetchdat & 7; - if (rm == 4) - { - uint8_t sib = fetchdat >> 8; + if (rm == 4) { + uint8_t sib = fetchdat >> 8; + (*op_pc)++; + + switch (mod) { + case 0: + if ((sib & 7) == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL EAX, imm32*/ + addlong(new_eaaddr); + (*op_pc) += 4; + } else { + addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + } + break; + case 1: + addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + addbyte(0x83); /*ADDL EAX, imm8*/ + addbyte(0xc0 | REG_EAX); + addbyte((int8_t) (rmdat >> 16)); (*op_pc)++; - - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - } - break; - case 1: - addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - addbyte(0x83); /*ADDL EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(rmdat >> 16)); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc) += 4; - break; - } - if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ - { - if (stack_offset < 0x80 || stack_offset >= 0xffffff80) - { - addbyte(0x83); - addbyte(0xc0 | REG_EAX); - addbyte(stack_offset); - } - else - { - addbyte(0x05); /*ADDL EAX, stack_offset*/ - addlong(stack_offset); - } - } - if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); - break; - case 1: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - break; - case 2: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ - addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(2); /*SHL EDI, 2*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - break; - case 3: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI reg*/ - addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(3); /*SHL EDI, 3*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - break; - } - } - } - else - { - if (!mod && rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - addbyte(0x8b); /*MOVL EAX, regs[rm].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[rm].l)); - cpu_state.eaaddr = cpu_state.regs[rm].l; - if (mod) - { - if (rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (mod == 1) - { - addbyte(0x83); /*ADD EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(fetchdat >> 8)); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x05); /*ADD EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - } - return op_ea_seg; -} - -static inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) -{ - if (op_32 & 0x200) - return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); - return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); -} - - -static inline void LOAD_STACK_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[ESP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static inline void LOAD_EBP_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[EBP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static inline void SP_MODIFY(int off) -{ - if (stack32) - { - if (off < 0x80) - { - addbyte(0x83); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addbyte(off); - } - else - { - addbyte(0x81); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addlong(off); - } - } - else - { - if (off < 0x80) - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x83); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addbyte(off); - } - else - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x81); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addword(off); - } - } -} - - -static inline void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - addbyte(0x83); - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - addbyte(0x83); - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: - addbyte(0x8a); /*MOV AL, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ + addlong(new_eaaddr); + addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + (*op_pc) += 4; break; + } + if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ + { + if (stack_offset < 0x80 || stack_offset >= 0xffffff80) { + addbyte(0x83); + addbyte(0xc0 | REG_EAX); + addbyte(stack_offset); + } else { + addbyte(0x05); /*ADDL EAX, stack_offset*/ + addlong(stack_offset); + } + } + if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (((sib >> 3) & 7) != 4) { + switch (sib >> 6) { + case 0: + addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); + break; + case 1: + addbyte(0x8B); + addbyte(0x45 | (REG_EDI << 3)); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ + addbyte(0x01); + addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ + addbyte(0x01); + addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ + break; + case 2: + addbyte(0x8B); + addbyte(0x45 | (REG_EDI << 3)); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ + addbyte(0xC1); + addbyte(0xE0 | REG_EDI); + addbyte(2); /*SHL EDI, 2*/ + addbyte(0x01); + addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ + break; + case 3: + addbyte(0x8B); + addbyte(0x45 | (REG_EDI << 3)); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI reg*/ + addbyte(0xC1); + addbyte(0xE0 | REG_EDI); + addbyte(3); /*SHL EDI, 3*/ + addbyte(0x01); + addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ + break; + } + } + } else { + if (!mod && rm == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL EAX, imm32*/ + addlong(new_eaaddr); + (*op_pc) += 4; + return op_ea_seg; + } + addbyte(0x8b); /*MOVL EAX, regs[rm].l*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[rm].l)); + cpu_state.eaaddr = cpu_state.regs[rm].l; + if (mod) { + if (rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (mod == 1) { + addbyte(0x83); /*ADD EAX, imm8*/ + addbyte(0xc0 | REG_EAX); + addbyte((int8_t) (fetchdat >> 8)); + (*op_pc)++; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x05); /*ADD EAX, imm32*/ + addlong(new_eaaddr); + (*op_pc) += 4; + } + } + } + return op_ea_seg; +} - default: - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - if (not) - addbyte(5+2+2+7+5+(timing_bt ? 4 : 0)); - else - addbyte(5+2+2); - CALL_FUNC((uintptr_t)CF_SET); +static __inline x86seg * +FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) +{ + if (op_32 & 0x200) + return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); + return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); +} + +static __inline void +LOAD_STACK_TO_EA(int off) +{ + if (stack32) { + addbyte(0x8b); /*MOVL EAX,[ESP]*/ + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + if (off) { + addbyte(0x83); /*ADD EAX, off*/ + addbyte(0xc0 | (0 << 3) | REG_EAX); + addbyte(off); + } + } else { + addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ + addbyte(0xb7); + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + if (off) { + addbyte(0x66); /*ADD AX, off*/ + addbyte(0x05); + addword(off); + } + } +} + +static __inline void +LOAD_EBP_TO_EA(int off) +{ + if (stack32) { + addbyte(0x8b); /*MOVL EAX,[EBP]*/ + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_EBP].l)); + if (off) { + addbyte(0x83); /*ADD EAX, off*/ + addbyte(0xc0 | (0 << 3) | REG_EAX); + addbyte(off); + } + } else { + addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ + addbyte(0xb7); + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_EBP].w)); + if (off) { + addbyte(0x66); /*ADD AX, off*/ + addbyte(0x05); + addword(off); + } + } +} + +static __inline void +SP_MODIFY(int off) +{ + if (stack32) { + if (off < 0x80) { + addbyte(0x83); /*ADD [ESP], off*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + addbyte(off); + } else { + addbyte(0x81); /*ADD [ESP], off*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + addlong(off); + } + } else { + if (off < 0x80) { + addbyte(0x66); /*ADD [SP], off*/ + addbyte(0x83); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + addbyte(off); + } else { + addbyte(0x66); /*ADD [SP], off*/ + addbyte(0x81); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + addword(off); + } + } +} + +static __inline void +TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) +{ + addbyte(0x66); /*CMPW host_reg, 0*/ + addbyte(0x83); + addbyte(0xc0 | 0x38 | host_reg); + addbyte(0); + addbyte(0x75); /*JNZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} +static __inline void +TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +{ + addbyte(0x83); /*CMPW host_reg, 0*/ + addbyte(0xc0 | 0x38 | host_reg); + addbyte(0); + addbyte(0x75); /*JNZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} + +static __inline void +TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) +{ + addbyte(0x66); /*CMPW host_reg, 0*/ + addbyte(0x83); + addbyte(0xc0 | 0x38 | host_reg); + addbyte(0); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} +static __inline void +TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +{ + addbyte(0x83); /*CMPW host_reg, 0*/ + addbyte(0xc0 | 0x38 | host_reg); + addbyte(0); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} + +static __inline void +BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) +{ + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + addbyte(0x8a); /*MOV AL, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3a); /*CMP AL, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x76); /*JBE*/ + else + addbyte(0x77); /*JNBE*/ + break; + case FLAGS_SUB16: + addbyte(0x66); /*MOV AX, flags_op1*/ + addbyte(0x8b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x66); /*CMP AX, flags_op2*/ + addbyte(0x3b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x76); /*JBE*/ + else + addbyte(0x77); /*JNBE*/ + break; + case FLAGS_SUB32: + addbyte(0x8b); /*MOV EAX, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3b); /*CMP EAX, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x76); /*JBE*/ + else + addbyte(0x77); /*JNBE*/ + break; + + default: + if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { + addbyte(0x83); /*CMP flags_res, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(flags_res)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + } else { + CALL_FUNC((uintptr_t) ZF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0x75); /*JNZ +*/ + } + if (not ) + addbyte(5 + 2 + 2 + 7 + 5 + (timing_bt ? 4 : 0)); + else + addbyte(5 + 2 + 2); + CALL_FUNC((uintptr_t) CF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + break; + } + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static inline void BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static __inline void +BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: - addbyte(0x8a); /*MOV AL, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + addbyte(0x8a); /*MOV AL, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3a); /*CMP AL, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7c); /*JL*/ + else + addbyte(0x7d); /*JNL*/ + break; + case FLAGS_SUB16: + addbyte(0x66); /*MOV AX, flags_op1*/ + addbyte(0x8b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x66); /*CMP AX, flags_op2*/ + addbyte(0x3b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7c); /*JL*/ + else + addbyte(0x7d); /*JNL*/ + break; + case FLAGS_SUB32: + addbyte(0x8b); /*MOV EAX, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3b); /*CMP EAX, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7c); /*JL*/ + else + addbyte(0x7d); /*JNL*/ + break; - default: - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + default: + CALL_FUNC((uintptr_t) NF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE BL*/ + addbyte(0x95); + addbyte(0xc3); + CALL_FUNC((uintptr_t) VF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE AL*/ + addbyte(0x95); + addbyte(0xc0); + addbyte(0x38); /*CMP AL, BL*/ + addbyte(0xd8); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + break; + } + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static inline void BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static __inline void +BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: - addbyte(0x8a); /*MOV AL, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + addbyte(0x8a); /*MOV AL, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3a); /*CMP AL, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7e); /*JLE*/ + else + addbyte(0x7f); /*JNLE*/ + break; + case FLAGS_SUB16: + addbyte(0x66); /*MOV AX, flags_op1*/ + addbyte(0x8b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x66); /*CMP AX, flags_op2*/ + addbyte(0x3b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7e); /*JLE*/ + else + addbyte(0x7f); /*JNLE*/ + break; + case FLAGS_SUB32: + addbyte(0x8b); /*MOV EAX, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3b); /*CMP EAX, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7e); /*JLE*/ + else + addbyte(0x7f); /*JNLE*/ + break; - default: - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - if (not) - addbyte(5+2+3+5+2+3+2+2+7+5+(timing_bt ? 4 : 0)); - else - addbyte(5+2+3+5+2+3+2+2); - - CALL_FUNC((uintptr_t)NF_SET); + default: + if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { + addbyte(0x83); /*CMP flags_res, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(flags_res)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + } else { + CALL_FUNC((uintptr_t) ZF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0x75); /*JNZ +*/ + } + if (not ) + addbyte(5 + 2 + 3 + 5 + 2 + 3 + 2 + 2 + 7 + 5 + (timing_bt ? 4 : 0)); + else + addbyte(5 + 2 + 3 + 5 + 2 + 3 + 2 + 2); + + CALL_FUNC((uintptr_t) NF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE BL*/ + addbyte(0x95); + addbyte(0xc3); + CALL_FUNC((uintptr_t) VF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE AL*/ + addbyte(0x95); + addbyte(0xc0); + addbyte(0x38); /*CMP AL, BL*/ + addbyte(0xd8); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + break; + } + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } - -static inline void FP_ENTER() +static __inline void +FP_ENTER(void) { - if (codegen_fpu_entered) - return; + if (codegen_fpu_entered) + return; - addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0x05); + addlong((uintptr_t) &cr0); + addbyte(0xc); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 7 + 5 + 5); + addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(op_old_pc); + addbyte(0xc7); /*MOV [ESP], 7*/ + addbyte(0x04); + addbyte(0x24); + addlong(7); + addbyte(0xe8); /*CALL x86_int*/ + addlong((uint32_t) x86_int - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + + codegen_fpu_entered = 1; +} + +static __inline void +FP_FLD(int reg) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xf3); /*MOVQ XMM0, ST[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0xf3); /*MOVQ XMM1, MM[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte(0x66); /*MOVQ ST[-1][EBP], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte(0x8a); /*MOV AL, tag[reg][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte(0x66); /*MOVQ MM[-1][EBP], XMM1*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte(0x88); /*MOV tag[-1][EBP], AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + } else { + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + } + + addbyte(0xdd); /*FLD [ST+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(0x07); + addbyte(0x8b); /*MOV EDX, [ST_i64+EAX]*/ + addbyte(0x54); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/ + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM) + 4); + addbyte(0x8a); /*MOV AL, [tag+EAX]*/ + addbyte(0x44); addbyte(0x05); - addlong((uintptr_t)&cr0); - addbyte(0xc); - addbyte(0x74); /*JZ +*/ - addbyte(7+7+5+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - addbyte(0xc7); /*MOV [ESP], 7*/ - addbyte(0x04); - addbyte(0x24); - addlong(7); - addbyte(0xe8); /*CALL x86_int*/ - addlong((uint32_t)x86_int - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - codegen_fpu_entered = 1; -} - -static inline void FP_FLD(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0xf3); /*MOVQ XMM1, MM[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x66); /*MOVQ ST[-1][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - addbyte(0x8a); /*MOV AL, tag[reg][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x66); /*MOVQ MM[-1][EBP], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); - addbyte(0x88); /*MOV tag[-1][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - else - { - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - } - - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(0x07); - addbyte(0x8b); /*MOV EDX, [ST_i64+EAX]*/ - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/ - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8a); /*MOV AL, [tag+EAX]*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/ - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - - addbyte(0x89); /*MOV [TOP], EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} - -static inline void FP_FST(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [tag+EAX]*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EAX], BL*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} - -static inline void FP_FXCH(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xf3); /*MOVQ XMM1, ST[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0xf3); /*MOVQ XMM2, MM[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); - addbyte(0x66); /*MOVQ ST[0][EBP], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xf3); /*MOVQ XMM3, MM[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x66); /*MOVQ MM[reg][EBP], XMM2*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(0x66); /*MOVQ MM[0][EBP], XMM3*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); - addbyte(0x8a); /*MOV AH, tag[reg][EBP]*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[0][EBP], AH*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - - addbyte(0xdd); /*FLD [ST+EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV CL, tag[EAX]*/ - addbyte(0x4c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x8a); /*MOV DL, tag[EBX]*/ - addbyte(0x54); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EBX], CL*/ - addbyte(0x4c); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EAX], DL*/ - addbyte(0x54); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0xbe); /*MOVL ESI, ST_int64*/ - addlong((uintptr_t)cpu_state.MM); - addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]*/ - addbyte(0x0c); - addbyte(0xc6); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]*/ - addbyte(0x14); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EBX*8], ECX*/ - addbyte(0x0c); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EAX*8], EDX*/ - addbyte(0x14); - addbyte(0xc6); - addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]+4*/ - addbyte(0x4c); - addbyte(0xc6); - addbyte(0x04); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]+4*/ - addbyte(0x54); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EBX*8]+4, ECX*/ - addbyte(0x4c); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EAX*8]+4, EDX*/ - addbyte(0x54); - addbyte(0xc6); - addbyte(0x04); - } -} - - -static inline void FP_LOAD_S() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0xd9); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xd9); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_D() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV ST[reg][EBP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0x89); /*MOV ST[reg][EBP]+4, EDX*/ - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0xdd); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_IW() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0x66); /*TEST AX, AX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0xdf); /*FILDw [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xdf); /*FILDw [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_IL() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0xdb); /*FILDl [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xdb); /*FILDl [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_IQ() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV MM[reg][EBP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0x89); /*MOV MM[reg][EBP]+4, EDX*/ - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q) + 4); - addbyte(0x0f); /*SETE AL*/ - addbyte(0x94); - addbyte(0xc0); - addbyte(0xdf); /*FILDq MM[reg][EBP]*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); - addbyte(0x0c); /*OR AL, TAG_UINT64*/ - addbyte(TAG_UINT64); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x89); /*MOV [ST_i64+EBX*8], EAX*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0x89); /*MOV [ST_i64+4+EBX*8], EDX*/ - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0xdf); /*FILDl [ST_i64+EBX*8]*/ - addbyte(0x6c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x0f); /*SETE AL*/ - addbyte(0x94); - addbyte(0xc0); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0c); /*OR AL, TAG_UINT64*/ - addbyte(TAG_UINT64); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} - -static inline void FP_LOAD_IMM_Q(uint64_t v) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xc7); /*MOV ST[reg][EBP], v*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - addlong(v & 0xffffffff); - addbyte(0xc7); /*MOV ST[reg][EBP]+4, v*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); - addlong(v >> 32); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(v ? 0 : 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addlong(v & 0xffffffff); - addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST) + 4); - addlong(v >> 32); - addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(v ? 0 : 1); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} - -static inline int FP_LOAD_REG(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[reg][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - addbyte(0xd9); /*FSTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV EAX, [ESP]*/ - addbyte(0x04 | (REG_EBX << 3)); - addbyte(0x24); - - return REG_EBX; -} - -static inline void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[reg][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - addbyte(0xdd); /*FSTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x04 | (REG_EBX << 3)); - addbyte(0x24); - addbyte(0x8b); /*MOV ECX, [ESP+4]*/ - addbyte(0x44 | (REG_ECX << 3)); - addbyte(0x24); - addbyte(0x04); - - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; -} - -static inline int FP_LOAD_REG_INT_W(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addbyte(0xdb); /*FISTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - - return REG_EBX; -} -static inline int FP_LOAD_REG_INT(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addbyte(0xdb); /*FISTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - - return REG_EBX; -} -static inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) - { - /*If we know the register was loaded with FILDq in this block and - has not been modified, then we can skip most of the conversion - and just load the 64-bit integer representation directly */ - addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - - return; - } - - addbyte(0xf6); /*TEST TAG[EBX], TAG_UINT64*/ + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x88); /*MOV [tag+EBX], AL*/ addbyte(0x44); addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_UINT64); - addbyte(0x74); /*JZ +*/ - addbyte(4+4+2); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/ + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/ + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM) + 4); + addbyte(0x89); /*MOV [TOP], EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + } +} + +static __inline void +FP_FST(int reg) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0x88); /*MOV tag[reg][EBP], AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + } else { + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FLD [ST+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [tag+EAX]*/ + addbyte(0x5c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + } + + addbyte(0xdd); /*FSTP [ST+EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x88); /*MOV [tag+EAX], BL*/ + addbyte(0x5c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} + +static __inline void +FP_FXCH(int reg) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0xf3); /*MOVQ XMM1, ST[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0xf3); /*MOVQ XMM2, MM[0][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x55); + addbyte((uint8_t) cpu_state_offset(MM[cpu_state.TOP].q)); + addbyte(0x66); /*MOVQ ST[0][EBP], XMM1*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0xf3); /*MOVQ XMM3, MM[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte(0x66); /*MOVQ MM[reg][EBP], XMM2*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x55); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(0x66); /*MOVQ MM[0][EBP], XMM3*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(MM[cpu_state.TOP].q)); + addbyte(0x8a); /*MOV AH, tag[reg][EBP]*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte(0x88); /*MOV tag[reg][EBP], AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte(0x88); /*MOV tag[0][EBP], AH*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + + addbyte(0xdd); /*FLD [ST+EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + addbyte(0xdd); /*FLD [ST+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP [ST+EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV CL, tag[EAX]*/ + addbyte(0x4c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x8a); /*MOV DL, tag[EBX]*/ + addbyte(0x54); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x88); /*MOV tag[EBX], CL*/ + addbyte(0x4c); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x88); /*MOV tag[EAX], DL*/ + addbyte(0x54); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0xbe); /*MOVL ESI, ST_int64*/ + addlong((uintptr_t) cpu_state.MM); + addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]*/ + addbyte(0x0c); + addbyte(0xc6); + addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]*/ + addbyte(0x14); + addbyte(0xde); + addbyte(0x89); /*MOV ST_int64[EBX*8], ECX*/ + addbyte(0x0c); + addbyte(0xde); + addbyte(0x89); /*MOV ST_int64[EAX*8], EDX*/ + addbyte(0x14); + addbyte(0xc6); + addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]+4*/ + addbyte(0x4c); + addbyte(0xc6); + addbyte(0x04); + addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]+4*/ + addbyte(0x54); + addbyte(0xde); + addbyte(0x04); + addbyte(0x89); /*MOV ST_int64[EBX*8]+4, ECX*/ + addbyte(0x4c); + addbyte(0xde); + addbyte(0x04); + addbyte(0x89); /*MOV ST_int64[EAX*8]+4, EDX*/ + addbyte(0x54); + addbyte(0xc6); + addbyte(0x04); + } +} + +static __inline void +FP_LOAD_S(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0xd9); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xd9); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} +static __inline void +FP_LOAD_D(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV ST[reg][EBP], EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV ST[reg][EBP]+4, EDX*/ + addbyte(0x55); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0xdd); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} +static __inline void +FP_LOAD_IW(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x66); /*MOV [ESP], AX*/ + addbyte(0x89); + addbyte(0x04); + addbyte(0x24); + addbyte(0x66); /*TEST AX, AX*/ + addbyte(0x85); + addbyte(0xc0); + addbyte(0xdf); /*FILDw [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xdf); /*FILDw [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} +static __inline void +FP_LOAD_IL(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0xdb); /*FILDl [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xdb); /*FILDl [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} +static __inline void +FP_LOAD_IQ(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV MM[reg][EBP], EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV MM[reg][EBP]+4, EDX*/ + addbyte(0x55); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q) + 4); + addbyte(0x0f); /*SETE AL*/ + addbyte(0x94); + addbyte(0xc0); + addbyte(0xdf); /*FILDq MM[reg][EBP]*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte(0x0c); /*OR AL, TAG_UINT64*/ + addbyte(TAG_UINT64); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x88); /*MOV tag[reg][EBP], AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x89); /*MOV [ST_i64+EBX*8], EAX*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV [ST_i64+4+EBX*8], EDX*/ + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM) + 4); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0xdf); /*FILDl [ST_i64+EBX*8]*/ + addbyte(0x6c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x0f); /*SETE AL*/ + addbyte(0x94); + addbyte(0xc0); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0c); /*OR AL, TAG_UINT64*/ + addbyte(TAG_UINT64); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x88); /*MOV [tag+EBX], AL*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} + +static __inline void +FP_LOAD_IMM_Q(uint64_t v) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xc7); /*MOV ST[reg][EBP], v*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addlong(v & 0xffffffff); + addbyte(0xc7); /*MOV ST[reg][EBP]+4, v*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); + addlong(v >> 32); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(v ? 0 : 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addlong(v & 0xffffffff); + addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST) + 4); + addlong(v >> 32); + addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(v ? 0 : 1); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + } +} + +static __inline int +FP_LOAD_REG(int reg) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xdd); /*FLD ST[reg][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } + addbyte(0xd9); /*FSTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0x8b); /*MOV EAX, [ESP]*/ + addbyte(0x04 | (REG_EBX << 3)); + addbyte(0x24); + + return REG_EBX; +} + +static __inline void +FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xdd); /*FLD ST[reg][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } + addbyte(0xdd); /*FSTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0x8b); /*MOV EBX, [ESP]*/ + addbyte(0x04 | (REG_EBX << 3)); + addbyte(0x24); + addbyte(0x8b); /*MOV ECX, [ESP+4]*/ + addbyte(0x44 | (REG_ECX << 3)); + addbyte(0x24); + addbyte(0x04); + + *host_reg1 = REG_EBX; + *host_reg2 = REG_ECX; +} + +static __inline int +FP_LOAD_REG_INT_W(int reg) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + addbyte(0xdb); /*FISTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); + addbyte(0x8b); /*MOV EBX, [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + + return REG_EBX; +} +static __inline int +FP_LOAD_REG_INT(int reg) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + addbyte(0xdb); /*FISTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); + addbyte(0x8b); /*MOV EBX, [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + + return REG_EBX; +} +static __inline void +FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) { + /*If we know the register was loaded with FILDq in this block and + has not been modified, then we can skip most of the conversion + and just load the 64-bit integer representation directly */ addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ addbyte(0x4c); addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); + addbyte((uint8_t) cpu_state_offset(MM) + 4); addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); + addbyte((uint8_t) cpu_state_offset(MM)); - addbyte(0xeb); /*JMP done*/ - addbyte(4+3+3+3+3+4); + return; + } - addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0xf6); /*TEST TAG[EBX], TAG_UINT64*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_UINT64); + addbyte(0x74); /*JZ +*/ + addbyte(4 + 4 + 2); + + addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM) + 4); + addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + + addbyte(0xeb); /*JMP done*/ + addbyte(4 + 3 + 3 + 3 + 3 + 4); + + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + addbyte(0xdf); /*FISTPQ [ESP]*/ + addbyte(0x3c); + addbyte(0x24); + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); + addbyte(0x8b); /*MOV EBX, [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0x8b); /*MOV ECX, 4[ESP]*/ + addbyte(0x4c); + addbyte(0x24); + addbyte(4); + + *host_reg1 = REG_EBX; + *host_reg2 = REG_ECX; +} + +static __inline void +FP_POP(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(3); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP + 1) & 7); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOVB tag[EAX], 3*/ addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addbyte(0xdf); /*FISTPQ [ESP]*/ - addbyte(0x3c); - addbyte(0x24); - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV ECX, 4[ESP]*/ - addbyte(0x4c); - addbyte(0x24); - addbyte(4); - - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(3); + addbyte(0x04); /*ADD AL, 1*/ + addbyte(1); + addbyte(0x24); /*AND AL, 7*/ + addbyte(7); + addbyte(0x88); /*MOV TOP, AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + } } - -static inline void FP_POP() +static __inline void +FP_POP2(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(3); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP + 1) & 7); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(3); - addbyte(0x04); /*ADD AL, 1*/ - addbyte(1); - addbyte(0x24); /*AND AL, 7*/ - addbyte(7); - addbyte(0x88); /*MOV TOP, AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} -static inline void FP_POP2() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(3); - addbyte(0xc6); /*MOVB tag[1][EBP], 3*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP+1)&7])); - addbyte(3); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP+2) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP + 2) & 7); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(3); - addbyte(0x04); /*ADD AL, 2*/ - addbyte(2); - addbyte(0x24); /*AND AL, 7*/ - addbyte(7); - addbyte(0x88); /*MOV TOP, AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(3); + addbyte(0xc6); /*MOVB tag[1][EBP], 3*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + 1) & 7])); + addbyte(3); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP+2) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP + 2) & 7); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOVB tag[EAX], 3*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(3); + addbyte(0x04); /*ADD AL, 2*/ + addbyte(2); + addbyte(0x24); /*AND AL, 7*/ + addbyte(7); + addbyte(0x88); /*MOV TOP, AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + } } #define FPU_ADD 0x00 @@ -2692,229 +2627,217 @@ static inline void FP_POP2() #define FPU_SUB 0x20 #define FPU_SUBR 0x28 -static inline void FP_OP_S(int op) +static __inline void +FP_OP_S(int op) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(TAG_NOT_UINT64); - addbyte(0xd8); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xd8); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xd8); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xd8); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } } -static inline void FP_OP_D(int op) +static __inline void +FP_OP_D(int op) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - } - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - } - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - } + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); } + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + } + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); + } + } } -static inline void FP_OP_IW(int op) +static __inline void +FP_OP_IW(int op) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(TAG_NOT_UINT64); - addbyte(0xde); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[0][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xde); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x66); /*MOV [ESP], AX*/ + addbyte(0x89); + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xde); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[0][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xde); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } } -static inline void FP_OP_IL(int op) +static __inline void +FP_OP_IL(int op) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(TAG_NOT_UINT64); - addbyte(0xda); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[0][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xda); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xda); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[0][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xda); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } } #if 0 -static inline void FP_OP_IQ(int op) +static __inline void FP_OP_IQ(int op) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2971,1037 +2894,1032 @@ static inline void FP_OP_IQ(int op) } #endif -static inline void FP_COMPARE_S() +static __inline void +FP_COMPARE_S(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xd8); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xd8); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xd8); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xd8); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static inline void FP_COMPARE_D() +static __inline void +FP_COMPARE_D(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xdc); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xdc); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static inline void FP_COMPARE_IW() +static __inline void +FP_COMPARE_IW(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xde); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xde); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x66); /*MOV [ESP], AX*/ + addbyte(0x89); + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xde); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xde); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static inline void FP_COMPARE_IL() +static __inline void +FP_COMPARE_IL(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xda); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xda); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xda); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xda); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static inline void FP_OP_REG(int op, int dst, int src) +static __inline void +FP_OP_REG(int op, int dst, int src) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - addbyte(0xdc); /*FADD ST[src][EBP]*/ - addbyte(0x45 | op); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - if (src) - { - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdc); /*FADD ST[EAX*8]*/ - addbyte(0x44 | op); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdc); /*FADD ST[EBX*8]*/ - addbyte(0x44 | op); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - } -} - -static inline void FP_COMPARE_REG(int dst, int src) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP ST[src][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - - if (src) - { - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EAX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EBX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} - -static inline void FP_FCHS() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xd9); /*FCHS*/ - addbyte(0xe0); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xd9); /*FCHS*/ - addbyte(0xe0); - addbyte(0xdd); /*FSTP ST[EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} - -static inline void UPDATE_NPXC(int reg) -{ - addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/ - addbyte(0x81); + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + addbyte(0xdc); /*FADD ST[src][EBP]*/ + addbyte(0x45 | op); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addword(~0xc00); - if (reg) - { - addbyte(0x66); /*AND reg, 0xc00*/ - addbyte(0x81); - addbyte(0xe0 | reg); - addword(0xc00); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (src || dst) { + addbyte(0x83); /*ADD EAX, 1*/ + addbyte(0xc0); + addbyte(src ? src : dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); } - else - { - addbyte(0x66); /*AND AX, 0xc00*/ - addbyte(0x25); - addword(0xc00); + + if (src) { + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdc); /*FADD ST[EAX*8]*/ + addbyte(0x44 | op); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP ST[EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdc); /*FADD ST[EBX*8]*/ + addbyte(0x44 | op); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP ST[EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); } - addbyte(0x66); /*OR cpu_state.new_npxc, reg*/ - addbyte(0x09); - addbyte(0x45 | (reg << 3)); - addbyte((uint8_t)cpu_state_offset(new_npxc)); + } } -static inline int ZERO_EXTEND_W_B(int reg) +static __inline void +FP_COMPARE_REG(int dst, int src) { - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static inline int ZERO_EXTEND_L_B(int reg) -{ - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static inline int ZERO_EXTEND_L_W(int reg) -{ - addbyte(0x0f); /*MOVZX regl, regw*/ - addbyte(0xb7); - addbyte(0xc0 | reg | (reg << 3)); - return reg; + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xdc); /*FCOMP ST[src][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (src || dst) { + addbyte(0x83); /*ADD EAX, 1*/ + addbyte(0xc0); + addbyte(src ? src : dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0 | C2 | C3)) >> 8); + + if (src) { + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdc); /*FCOMP ST[EAX*8]*/ + addbyte(0x44 | 0x18); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdc); /*FCOMP ST[EBX*8]*/ + addbyte(0x44 | 0x18); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } + + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static inline int SIGN_EXTEND_W_B(int reg) +static __inline void +FP_FCHS(void) { - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static inline int SIGN_EXTEND_L_B(int reg) -{ - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static inline int SIGN_EXTEND_L_W(int reg) -{ - addbyte(0x0f); /*MOVSX regl, regw*/ - addbyte(0xbf); - addbyte(0xc0 | reg | (reg << 3)); - return reg; + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0xd9); /*FCHS*/ + addbyte(0xe0); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + + addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xd9); /*FCHS*/ + addbyte(0xe0); + addbyte(0xdd); /*FSTP ST[EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } } -static inline int COPY_REG(int src_reg) +static __inline void +UPDATE_NPXC(int reg) { - return src_reg; + addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/ + addbyte(0x81); + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + addword(~0xc00); + if (reg) { + addbyte(0x66); /*AND reg, 0xc00*/ + addbyte(0x81); + addbyte(0xe0 | reg); + addword(0xc00); + } else { + addbyte(0x66); /*AND AX, 0xc00*/ + addbyte(0x25); + addword(0xc00); + } + addbyte(0x66); /*OR cpu_state.new_npxc, reg*/ + addbyte(0x09); + addbyte(0x45 | (reg << 3)); + addbyte((uint8_t) cpu_state_offset(new_npxc)); } -static inline void SET_BITS(uintptr_t addr, uint32_t val) +static __inline int +ZERO_EXTEND_W_B(int reg) { - if (val & ~0xff) - { - addbyte(0x81); - addbyte(0x0d); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x80); - addbyte(0x0d); - addlong(addr); - addbyte(val); - } + addbyte(0x0f); /*MOVZX regl, regb*/ + addbyte(0xb6); + addbyte(0xc0 | reg | (reg << 3)); + return reg; } -static inline void CLEAR_BITS(uintptr_t addr, uint32_t val) +static __inline int +ZERO_EXTEND_L_B(int reg) { - if (val & ~0xff) - { - addbyte(0x81); - addbyte(0x25); - addlong(addr); - addlong(~val); - } - else - { - addbyte(0x80); - addbyte(0x25); - addlong(addr); - addbyte(~val); - } + addbyte(0x0f); /*MOVZX regl, regb*/ + addbyte(0xb6); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} +static __inline int +ZERO_EXTEND_L_W(int reg) +{ + addbyte(0x0f); /*MOVZX regl, regw*/ + addbyte(0xb7); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} + +static __inline int +SIGN_EXTEND_W_B(int reg) +{ + addbyte(0x0f); /*MOVSX regl, regb*/ + addbyte(0xbe); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} +static __inline int +SIGN_EXTEND_L_B(int reg) +{ + addbyte(0x0f); /*MOVSX regl, regb*/ + addbyte(0xbe); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} +static __inline int +SIGN_EXTEND_L_W(int reg) +{ + addbyte(0x0f); /*MOVSX regl, regw*/ + addbyte(0xbf); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} + +static __inline int +COPY_REG(int src_reg) +{ + return src_reg; +} + +static __inline void +SET_BITS(uintptr_t addr, uint32_t val) +{ + if (val & ~0xff) { + addbyte(0x81); + addbyte(0x0d); + addlong(addr); + addlong(val); + } else { + addbyte(0x80); + addbyte(0x0d); + addlong(addr); + addbyte(val); + } +} +static __inline void +CLEAR_BITS(uintptr_t addr, uint32_t val) +{ + if (val & ~0xff) { + addbyte(0x81); + addbyte(0x25); + addlong(addr); + addlong(~val); + } else { + addbyte(0x80); + addbyte(0x25); + addlong(addr); + addbyte(~val); + } } #define LOAD_Q_REG_1 REG_EAX #define LOAD_Q_REG_2 REG_EDX -static inline void MMX_ENTER() +static __inline void +MMX_ENTER(void) { - if (codegen_mmx_entered) - return; + if (codegen_mmx_entered) + return; - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x05); - addlong((uintptr_t)&cr0); - addbyte(0xc); - addbyte(0x74); /*JZ +*/ - addbyte(7+7+5+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - addbyte(0xc7); /*MOV [ESP], 7*/ - addbyte(0x04); - addbyte(0x24); - addlong(7); - addbyte(0xe8); /*CALL x86_int*/ - addlong((uint32_t)x86_int - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0x05); + addlong((uintptr_t) &cr0); + addbyte(0xc); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 7 + 5 + 5); + addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(op_old_pc); + addbyte(0xc7); /*MOV [ESP], 7*/ + addbyte(0x04); + addbyte(0x24); + addlong(7); + addbyte(0xe8); /*CALL x86_int*/ + addlong((uint32_t) x86_int - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xc6); /*MOV ISMMX, 1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ismmx)); - addbyte(1); - addbyte(0x89); /*MOV TOP, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV tag, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV tag+4, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[4])); + addbyte(0x31); /*XOR EAX, EAX*/ + addbyte(0xc0); + addbyte(0xc6); /*MOV ISMMX, 1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ismmx)); + addbyte(1); + addbyte(0x89); /*MOV TOP, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV tag, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x89); /*MOV tag+4, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[4])); - codegen_mmx_entered = 1; + codegen_mmx_entered = 1; } extern int mmx_ebx_ecx_loaded; -static inline int LOAD_MMX_D(int guest_reg) +static __inline int +LOAD_MMX_D(int guest_reg) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 100; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 100; - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x8b); /*MOV EBX, reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); - return host_reg; + return host_reg; } -static inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) +static __inline void +LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) { - if (!mmx_ebx_ecx_loaded) - { - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; - mmx_ebx_ecx_loaded = 1; - } - else - { - *host_reg1 = REG_EAX; - *host_reg2 = REG_EDX; - } + if (!mmx_ebx_ecx_loaded) { + *host_reg1 = REG_EBX; + *host_reg2 = REG_ECX; + mmx_ebx_ecx_loaded = 1; + } else { + *host_reg1 = REG_EAX; + *host_reg2 = REG_EDX; + } - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x45 | ((*host_reg1) << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - addbyte(0x8b); /*MOV ECX, reg+4*/ - addbyte(0x45 | ((*host_reg2) << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); + addbyte(0x8b); /*MOV EBX, reg*/ + addbyte(0x45 | ((*host_reg1) << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x8b); /*MOV ECX, reg+4*/ + addbyte(0x45 | ((*host_reg2) << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[1])); } -static inline int LOAD_MMX_Q_MMX(int guest_reg) +static __inline int +LOAD_MMX_Q_MMX(int guest_reg) { - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = guest_reg; + int dst_reg = find_host_xmm_reg(); + host_reg_xmm_mapping[dst_reg] = guest_reg; - addbyte(0xf3); /*MOVQ dst_reg,[reg]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45 | (dst_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + addbyte(0xf3); /*MOVQ dst_reg,[reg]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45 | (dst_reg << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); - return dst_reg; + return dst_reg; } -static inline int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) +static __inline int +LOAD_INT_TO_MMX(int src_reg1, int src_reg2) { - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = 100; + int dst_reg = find_host_xmm_reg(); + host_reg_xmm_mapping[dst_reg] = 100; - addbyte(0x66); /*MOVD dst_reg, src_reg1*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (dst_reg << 3) | src_reg1); - addbyte(0x66); /*MOVD XMM7, src_reg2*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (7 << 3) | src_reg2); - addbyte(0x66); /*PUNPCKLDQ dst_reg, XMM7*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | 7 | (dst_reg << 3)); + addbyte(0x66); /*MOVD dst_reg, src_reg1*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc0 | (dst_reg << 3) | src_reg1); + addbyte(0x66); /*MOVD XMM7, src_reg2*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc0 | (7 << 3) | src_reg2); + addbyte(0x66); /*PUNPCKLDQ dst_reg, XMM7*/ + addbyte(0x0f); + addbyte(0x62); + addbyte(0xc0 | 7 | (dst_reg << 3)); - return dst_reg; + return dst_reg; } -static inline void STORE_MMX_LQ(int guest_reg, int host_reg1) +static __inline void +STORE_MMX_LQ(int guest_reg, int host_reg1) { - addbyte(0xC7); /*MOVL [reg],0*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); - addlong(0); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg1 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0xC7); /*MOVL [reg],0*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[1])); + addlong(0); + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x45 | (host_reg1 << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); } -static inline void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) +static __inline void +STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) { - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg1 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg2 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x45 | (host_reg1 << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x45 | (host_reg2 << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[1])); } -static inline void STORE_MMX_Q_MMX(int guest_reg, int host_reg) +static __inline void +STORE_MMX_Q_MMX(int guest_reg, int host_reg) { - addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); } -#define MMX_x86_OP(name, opcode) \ -static inline void MMX_ ## name(int dst_reg, int src_reg) \ -{ \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ -} +#define MMX_x86_OP(name, opcode) \ + static __inline void MMX_##name(int dst_reg, int src_reg) \ + { \ + addbyte(0x66); /*op dst_reg, src_reg*/ \ + addbyte(0x0f); \ + addbyte(opcode); \ + addbyte(0xc0 | (dst_reg << 3) | src_reg); \ + } -MMX_x86_OP(AND, 0xdb) -MMX_x86_OP(ANDN, 0xdf) -MMX_x86_OP(OR, 0xeb) -MMX_x86_OP(XOR, 0xef) +MMX_x86_OP(AND, 0xdb) + MMX_x86_OP(ANDN, 0xdf) + MMX_x86_OP(OR, 0xeb) + MMX_x86_OP(XOR, 0xef) -MMX_x86_OP(ADDB, 0xfc) -MMX_x86_OP(ADDW, 0xfd) -MMX_x86_OP(ADDD, 0xfe) -MMX_x86_OP(ADDSB, 0xec) -MMX_x86_OP(ADDSW, 0xed) -MMX_x86_OP(ADDUSB, 0xdc) -MMX_x86_OP(ADDUSW, 0xdd) + MMX_x86_OP(ADDB, 0xfc) + MMX_x86_OP(ADDW, 0xfd) + MMX_x86_OP(ADDD, 0xfe) + MMX_x86_OP(ADDSB, 0xec) + MMX_x86_OP(ADDSW, 0xed) + MMX_x86_OP(ADDUSB, 0xdc) + MMX_x86_OP(ADDUSW, 0xdd) -MMX_x86_OP(SUBB, 0xf8) -MMX_x86_OP(SUBW, 0xf9) -MMX_x86_OP(SUBD, 0xfa) -MMX_x86_OP(SUBSB, 0xe8) -MMX_x86_OP(SUBSW, 0xe9) -MMX_x86_OP(SUBUSB, 0xd8) -MMX_x86_OP(SUBUSW, 0xd9) + MMX_x86_OP(SUBB, 0xf8) + MMX_x86_OP(SUBW, 0xf9) + MMX_x86_OP(SUBD, 0xfa) + MMX_x86_OP(SUBSB, 0xe8) + MMX_x86_OP(SUBSW, 0xe9) + MMX_x86_OP(SUBUSB, 0xd8) + MMX_x86_OP(SUBUSW, 0xd9) -MMX_x86_OP(PUNPCKLBW, 0x60); + MMX_x86_OP(PUNPCKLBW, 0x60); MMX_x86_OP(PUNPCKLWD, 0x61); MMX_x86_OP(PUNPCKLDQ, 0x62); -MMX_x86_OP(PCMPGTB, 0x64); -MMX_x86_OP(PCMPGTW, 0x65); -MMX_x86_OP(PCMPGTD, 0x66); +MMX_x86_OP(PCMPGTB, 0x64); +MMX_x86_OP(PCMPGTW, 0x65); +MMX_x86_OP(PCMPGTD, 0x66); -MMX_x86_OP(PCMPEQB, 0x74); -MMX_x86_OP(PCMPEQW, 0x75); -MMX_x86_OP(PCMPEQD, 0x76); +MMX_x86_OP(PCMPEQB, 0x74); +MMX_x86_OP(PCMPEQW, 0x75); +MMX_x86_OP(PCMPEQD, 0x76); -MMX_x86_OP(PSRLW, 0xd1); -MMX_x86_OP(PSRLD, 0xd2); -MMX_x86_OP(PSRLQ, 0xd3); -MMX_x86_OP(PSRAW, 0xe1); -MMX_x86_OP(PSRAD, 0xe2); -MMX_x86_OP(PSLLW, 0xf1); -MMX_x86_OP(PSLLD, 0xf2); -MMX_x86_OP(PSLLQ, 0xf3); +MMX_x86_OP(PSRLW, 0xd1); +MMX_x86_OP(PSRLD, 0xd2); +MMX_x86_OP(PSRLQ, 0xd3); +MMX_x86_OP(PSRAW, 0xe1); +MMX_x86_OP(PSRAD, 0xe2); +MMX_x86_OP(PSLLW, 0xf1); +MMX_x86_OP(PSLLD, 0xf2); +MMX_x86_OP(PSLLQ, 0xf3); -MMX_x86_OP(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); +MMX_x86_OP(PMULLW, 0xd5); +MMX_x86_OP(PMULHW, 0xe5); MMX_x86_OP(PMADDWD, 0xf5); -static inline void MMX_PACKSSWB(int dst_reg, int src_reg) +static __inline void +MMX_PACKSSWB(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x63); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x63); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static inline void MMX_PACKUSWB(int dst_reg, int src_reg) +static __inline void +MMX_PACKUSWB(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static inline void MMX_PACKSSDW(int dst_reg, int src_reg) +static __inline void +MMX_PACKSSDW(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHBW(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHWD(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x61); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHDQ(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x62); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static inline void MMX_PSRLW_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static inline void MMX_PSRAW_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static inline void MMX_PSLLW_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } -static inline void MMX_PSRLD_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static inline void MMX_PSRAD_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static inline void MMX_PSLLD_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } -static inline void MMX_PSRLQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static inline void MMX_PSRAQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static inline void MMX_PSLLQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } - -static inline void SAVE_EA() +static __inline void +SAVE_EA(void) { - addbyte(0x89); /*MOV [ESP+12], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(12); + addbyte(0x89); /*MOV [ESP+12], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(12); } -static inline void LOAD_EA() +static __inline void +LOAD_EA(void) { - addbyte(0x8b); /*MOV EAX, [ESP+12]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(12); + addbyte(0x8b); /*MOV EAX, [ESP+12]*/ + addbyte(0x44); + addbyte(0x24); + addbyte(12); } #define MEM_CHECK_WRITE_B MEM_CHECK_WRITE -static inline void MEM_CHECK_WRITE(x86seg *seg) +static __inline void +MEM_CHECK_WRITE(x86seg *seg) { - CHECK_SEG_WRITE(seg); - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_check_write*/ - addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - LOAD_EA(); + CHECK_SEG_WRITE(seg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_check_write*/ + addlong(mem_check_write - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + LOAD_EA(); } -static inline void MEM_CHECK_WRITE_W(x86seg *seg) +static __inline void +MEM_CHECK_WRITE_W(x86seg *seg) { - CHECK_SEG_WRITE(seg); - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_check_write_w*/ - addlong(mem_check_write_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - LOAD_EA(); + CHECK_SEG_WRITE(seg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_check_write_w*/ + addlong(mem_check_write_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + LOAD_EA(); } -static inline void MEM_CHECK_WRITE_L(x86seg *seg) +static __inline void +MEM_CHECK_WRITE_L(x86seg *seg) { - CHECK_SEG_WRITE(seg); - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_check_write_l*/ - addlong(mem_check_write_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - LOAD_EA(); + CHECK_SEG_WRITE(seg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_check_write_l*/ + addlong(mem_check_write_l - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + LOAD_EA(); } -static inline void LOAD_SEG(int host_reg, void *seg) +static __inline void +LOAD_SEG(int host_reg, void *seg) { - addbyte(0xc7); /*MOV [ESP+4], seg*/ - addbyte(0x44); - addbyte(0x24); - addbyte(4); - addlong((uint32_t)seg); - addbyte(0x89); /*MOV [ESP], host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(0x24); - CALL_FUNC((uintptr_t)loadseg); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0xc7); /*MOV [ESP+4], seg*/ + addbyte(0x44); + addbyte(0x24); + addbyte(4); + addlong((uint32_t) seg); + addbyte(0x89); /*MOV [ESP], host_reg*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(0x24); + CALL_FUNC((uintptr_t) loadseg); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } diff --git a/src/codegen/codegen_ops_xchg.h b/src/codegen/codegen_ops_xchg.h index a51f42eda..071acc3d8 100644 --- a/src/codegen/codegen_ops_xchg.h +++ b/src/codegen/codegen_ops_xchg.h @@ -1,16 +1,16 @@ -#define OP_XCHG_AX_(reg) \ - static uint32_t ropXCHG_AX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int ax_reg, host_reg, temp_reg; \ - \ - ax_reg = LOAD_REG_W(REG_AX); \ - host_reg = LOAD_REG_W(REG_ ## reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_W_RELEASE(ax_reg, REG_ ## reg); \ - STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ - \ - return op_pc; \ - } +#define OP_XCHG_AX_(reg) \ + static uint32_t ropXCHG_AX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int ax_reg, host_reg, temp_reg; \ + \ + ax_reg = LOAD_REG_W(REG_AX); \ + host_reg = LOAD_REG_W(REG_##reg); \ + temp_reg = COPY_REG(host_reg); \ + STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \ + STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ + \ + return op_pc; \ + } OP_XCHG_AX_(BX) OP_XCHG_AX_(CX) @@ -20,19 +20,19 @@ OP_XCHG_AX_(DI) OP_XCHG_AX_(SP) OP_XCHG_AX_(BP) -#define OP_XCHG_EAX_(reg) \ - static uint32_t ropXCHG_EAX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int eax_reg, host_reg, temp_reg; \ - \ - eax_reg = LOAD_REG_L(REG_EAX); \ - host_reg = LOAD_REG_L(REG_ ## reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_L_RELEASE(eax_reg, REG_ ## reg); \ - STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ - \ - return op_pc; \ - } +#define OP_XCHG_EAX_(reg) \ + static uint32_t ropXCHG_EAX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int eax_reg, host_reg, temp_reg; \ + \ + eax_reg = LOAD_REG_L(REG_EAX); \ + host_reg = LOAD_REG_L(REG_##reg); \ + temp_reg = COPY_REG(host_reg); \ + STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \ + STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ + \ + return op_pc; \ + } OP_XCHG_EAX_(EBX) OP_XCHG_EAX_(ECX) @@ -42,48 +42,51 @@ OP_XCHG_EAX_(EDI) OP_XCHG_EAX_(ESP) OP_XCHG_EAX_(EBP) -static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg, temp_reg; + int src_reg, dst_reg, temp_reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) != 0xc0) + return 0; - dst_reg = LOAD_REG_B(fetchdat & 7); - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7); + dst_reg = LOAD_REG_B(fetchdat & 7); + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); + temp_reg = COPY_REG(src_reg); + STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7); + STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg, temp_reg; + int src_reg, dst_reg, temp_reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) != 0xc0) + return 0; - dst_reg = LOAD_REG_W(fetchdat & 7); - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7); + dst_reg = LOAD_REG_W(fetchdat & 7); + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); + temp_reg = COPY_REG(src_reg); + STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7); + STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg, temp_reg; + int src_reg, dst_reg, temp_reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) != 0xc0) + return 0; - dst_reg = LOAD_REG_L(fetchdat & 7); - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7); + dst_reg = LOAD_REG_L(fetchdat & 7); + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); + temp_reg = COPY_REG(src_reg); + STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7); + STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7); - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index 7a9c00519..6939819d4 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -1,1188 +1,1116 @@ #if defined __amd64__ || defined _M_X64 -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include "x86.h" -#include "x86_flags.h" -#include "x86_ops.h" -#include "x87.h" -#include <86box/mem.h> +# include +# include +# include +# include +# include +# define HAVE_STDARG_H +# include <86box/86box.h> +# include "cpu.h" +# include "x86.h" +# include "x86_flags.h" +# include "x86_ops.h" +# include "x87.h" +# include <86box/mem.h> -#include "386_common.h" +# include "386_common.h" -#include "codegen.h" -#include "codegen_accumulate.h" -#include "codegen_ops.h" -#include "codegen_ops_x86-64.h" +# include "codegen.h" +# include "codegen_accumulate.h" +# include "codegen_ops.h" +# include "codegen_ops_x86-64.h" -#if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) -#include -#include -#endif -#if _WIN64 -#include -#endif +# if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) +# include +# include +# endif +# if _WIN64 +# include +# endif -int codegen_flat_ds, codegen_flat_ss; -int codegen_flags_changed = 0; -int codegen_fpu_entered = 0; -int codegen_fpu_loaded_iq[8]; -int codegen_reg_loaded[8]; -x86seg *op_ea_seg; -int op_ssegs; +int codegen_flat_ds, codegen_flat_ss; +int codegen_flags_changed = 0; +int codegen_fpu_entered = 0; +int codegen_fpu_loaded_iq[8]; +int codegen_reg_loaded[8]; +x86seg *op_ea_seg; +int op_ssegs; uint32_t op_old_pc; uint32_t recomp_page = -1; -int host_reg_mapping[NR_HOST_REGS]; -int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; -codeblock_t *codeblock; +int host_reg_mapping[NR_HOST_REGS]; +int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; +codeblock_t *codeblock; codeblock_t **codeblock_hash; -int codegen_mmx_entered = 0; +int codegen_mmx_entered = 0; -int block_current = 0; +int block_current = 0; static int block_num; -int block_pos; +int block_pos; uint32_t codegen_endpc; -int codegen_block_cycles; +int codegen_block_cycles; static int codegen_block_ins; static int codegen_block_full_ins; static uint32_t last_op32; -static x86seg *last_ea_seg; -static int last_ssegs; +static x86seg *last_ea_seg; +static int last_ssegs; -void codegen_init() +void +codegen_init(void) { - int c; + int c; -#if _WIN64 - codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#elif defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) - codeblock = mmap(NULL, BLOCK_SIZE * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); -#else - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); -#endif - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); +# if _WIN64 + codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +# elif defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) + codeblock = mmap(NULL, BLOCK_SIZE * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); +# else + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); +# endif + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].valid = 0; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].valid = 0; } -void codegen_reset() +void +codegen_reset(void) { - int c; + int c; - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - mem_reset_page_blocks(); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + mem_reset_page_blocks(); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].valid = 0; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].valid = 0; } -void dump_block() +void +dump_block(void) { } -static void add_to_block_list(codeblock_t *block) +static void +add_to_block_list(codeblock_t *block) { - codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; + codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; - if (!block->page_mask) - fatal("add_to_block_list - mask = 0\n"); + if (!block->page_mask) + fatal("add_to_block_list - mask = 0\n"); - if (block_prev) - { - block->next = block_prev; - block_prev->prev = block; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - else - { - block->next = NULL; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - - if (block->next) - { - if (block->next->valid == 0) - fatal("block->next->valid=0 %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); - } - - if (block->page_mask2) - { - block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; - - if (block_prev) - { - block->next_2 = block_prev; - block_prev->prev_2 = block; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - else - { - block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } + if (block_prev) { + block->next = block_prev; + block_prev->prev = block; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } else { + block->next = NULL; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } + + if (block->next) { + if (block->next->valid == 0) + fatal("block->next->valid=0 %p %p %x %x\n", (void *) block->next, (void *) codeblock, block_current, block_pos); + } + + if (block->page_mask2) { + block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; + + if (block_prev) { + block->next_2 = block_prev; + block_prev->prev_2 = block; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; + } else { + block->next_2 = NULL; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; } + } } -static void remove_from_block_list(codeblock_t *block, uint32_t pc) -{ - if (!block->page_mask) - return; - - if (block->prev) - { - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } - else - { - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; - if (block->next) - block->next->prev = NULL; - else - mem_flush_write_page(block->phys, 0); - } - if (!block->page_mask2) - { - if (block->prev_2 || block->next_2) - fatal("Invalid block_2\n"); - return; - } - - if (block->prev_2) - { - block->prev_2->next_2 = block->next_2; - if (block->next_2) - block->next_2->prev_2 = block->prev_2; - } - else - { - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; - if (block->next_2) - block->next_2->prev_2 = NULL; - else - mem_flush_write_page(block->phys_2, 0); - } -} - -static void delete_block(codeblock_t *block) -{ - uint32_t old_pc = block->pc; - - if (block == codeblock_hash[HASH(block->phys)]) - codeblock_hash[HASH(block->phys)] = NULL; - - if (block->valid == 0) - fatal("Deleting deleted block\n"); - block->valid = 0; - - codeblock_tree_delete(block); - remove_from_block_list(block, old_pc); -} - -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) -{ - struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask) - { - delete_block(block); - } - if (block == block->next) - fatal("Broken 1\n"); - block = block->next; - } - - block = page->block_2[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask2) - { - delete_block(block); - } - if (block == block->next_2) - fatal("Broken 2\n"); - block = block->next_2; - } -} - -void codegen_block_init(uint32_t phys_addr) -{ - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; - - if (!page->block[(phys_addr >> 10) & 3]) - mem_flush_write_page(phys_addr, cs+cpu_state.pc); - - block_current = (block_current + 1) & BLOCK_MASK; - block = &codeblock[block_current]; - - if (block->valid != 0) - { - delete_block(block); - } - block_num = HASH(phys_addr); - codeblock_hash[block_num] = &codeblock[block_current]; - - block->valid = 1; - block->ins = 0; - block->pc = cs + cpu_state.pc; - block->_cs = cs; - block->pnt = block_current; - block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - block->dirty_mask2 = NULL; - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - block->page_mask = 0; - block->flags = 0; - block->status = cpu_cur_status; - - block->was_recompiled = 0; - - recomp_page = block->phys & ~0xfff; - - codeblock_tree_add(block); -} - -void codegen_block_start_recompile(codeblock_t *block) -{ - page_t *page = &pages[block->phys >> 12]; - uintptr_t rip_rel; - - if (!page->block[(block->phys >> 10) & 3]) - mem_flush_write_page(block->phys, cs+cpu_state.pc); - - block_num = HASH(block->phys); - block_current = block->pnt; - - if (block->pc != cs + cpu_state.pc || block->was_recompiled) - fatal("Recompile to used block!\n"); - - block->status = cpu_cur_status; - - block_pos = BLOCK_GPF_OFFSET; -#ifdef OLD_GPF -#if _WIN64 - addbyte(0x48); /*XOR RCX, RCX*/ - addbyte(0x31); - addbyte(0xc9); - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); -#else - addbyte(0x48); /*XOR RDI, RDI*/ - addbyte(0x31); - addbyte(0xff); - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); -#endif - call(block, (uintptr_t)x86gpf); - while (block_pos < BLOCK_EXIT_OFFSET) - addbyte(0x90); /*NOP*/ -#else - addbyte(0xC6); /*MOVB ABRT_GPF,(abrt)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(ABRT_GPF); - addbyte(0x31); /* xor eax,eax */ - addbyte(0xc0); - addbyte(0x89); /*MOVB eax,(abrt_error)*/ - addbyte(0x85); - rip_rel = ((uintptr_t)&cpu_state) + 128; - rip_rel = ((uintptr_t) &(abrt_error)) - rip_rel; - addlong((uint32_t) rip_rel); -#endif - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x48); /*ADDL $40,%rsp*/ - addbyte(0x83); - addbyte(0xC4); - addbyte(0x28); - addbyte(0x41); /*POP R15*/ - addbyte(0x5f); - addbyte(0x41); /*POP R14*/ - addbyte(0x5e); - addbyte(0x41); /*POP R13*/ - addbyte(0x5d); - addbyte(0x41); /*POP R12*/ - addbyte(0x5c); - addbyte(0x5f); /*POP RDI*/ - addbyte(0x5e); /*POP RSI*/ - addbyte(0x5d); /*POP RBP*/ - addbyte(0x5b); /*POP RDX*/ - addbyte(0xC3); /*RET*/ - cpu_block_end = 0; - block_pos = 0; /*Entry code*/ - addbyte(0x53); /*PUSH RBX*/ - addbyte(0x55); /*PUSH RBP*/ - addbyte(0x56); /*PUSH RSI*/ - addbyte(0x57); /*PUSH RDI*/ - addbyte(0x41); /*PUSH R12*/ - addbyte(0x54); - addbyte(0x41); /*PUSH R13*/ - addbyte(0x55); - addbyte(0x41); /*PUSH R14*/ - addbyte(0x56); - addbyte(0x41); /*PUSH R15*/ - addbyte(0x57); - addbyte(0x48); /*SUBL $40,%rsp*/ - addbyte(0x83); - addbyte(0xEC); - addbyte(0x28); - addbyte(0x48); /*MOVL RBP, &cpu_state*/ - addbyte(0xBD); - addquad(((uintptr_t)&cpu_state) + 128); - - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; - - codegen_block_cycles = 0; - codegen_timing_block_start(); - - codegen_block_ins = 0; - codegen_block_full_ins = 0; - - recomp_page = block->phys & ~0xfff; - - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; - - codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = - codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - - cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; - - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - - block->was_recompiled = 1; - - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); -} - -void codegen_block_remove() -{ - codeblock_t *block = &codeblock[block_current]; - - delete_block(block); - - recomp_page = -1; -} - -void codegen_block_generate_end_mask() -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; - - block->endpc = codegen_endpc; - - block->page_mask = 0; - start_pc = (block->pc & 0x3ff) & ~15; - if ((block->pc ^ block->endpc) & ~0x3ff) - end_pc = 0x3ff & ~15; - else - end_pc = (block->endpc & 0x3ff) & ~15; - if (end_pc < start_pc) - end_pc = 0x3ff; - start_pc >>= PAGE_MASK_SHIFT; - end_pc >>= PAGE_MASK_SHIFT; - - for (; start_pc <= end_pc; start_pc++) - block->page_mask |= ((uint64_t)1 << start_pc); - - pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; - - block->phys_2 = -1; - block->page_mask2 = 0; - block->next_2 = block->prev_2 = NULL; - if ((block->pc ^ block->endpc) & ~0x3ff) - { - block->phys_2 = get_phys_noabrt(block->endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; - - start_pc = 0; - end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; - for (; start_pc <= end_pc; start_pc++) - block->page_mask2 |= ((uint64_t)1 << start_pc); - page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; - - if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) - mem_flush_write_page(block->phys_2, block->endpc); - - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (block->next_2->valid == 0) - fatal("block->next_2->valid=0 %p\n", (void *)block->next_2); - } - - block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - } - } - - recomp_page = -1; -} - -void codegen_block_end() -{ - codeblock_t *block = &codeblock[block_current]; - - codegen_block_generate_end_mask(); - add_to_block_list(block); -} - -void codegen_block_end_recompile(codeblock_t *block) -{ - codegen_timing_block_end(); - codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); - - codegen_accumulate_flush(); - - addbyte(0x48); /*ADDL $40,%rsp*/ - addbyte(0x83); - addbyte(0xC4); - addbyte(0x28); - addbyte(0x41); /*POP R15*/ - addbyte(0x5f); - addbyte(0x41); /*POP R14*/ - addbyte(0x5e); - addbyte(0x41); /*POP R13*/ - addbyte(0x5d); - addbyte(0x41); /*POP R12*/ - addbyte(0x5c); - addbyte(0x5f); /*POP RDI*/ - addbyte(0x5e); /*POP RSI*/ - addbyte(0x5d); /*POP RBP*/ - addbyte(0x5b); /*POP RDX*/ - addbyte(0xC3); /*RET*/ - - if (block_pos > BLOCK_GPF_OFFSET) - fatal("Over limit!\n"); - - remove_from_block_list(block, block->pc); - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - codegen_block_generate_end_mask(); - add_to_block_list(block); -} - -void codegen_flush() +static void +remove_from_block_list(codeblock_t *block, uint32_t pc) { + if (!block->page_mask) return; -} -static int opcode_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ - - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ -}; -int opcode_0f_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ - - 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ - 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ -}; - -void codegen_debug() -{ -} - -static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) -{ - if (!cpu_mod && cpu_rm == 6) - { - addbyte(0xC7); /*MOVL $0,(ssegs)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } + if (block->prev) { + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } else { + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; + if (block->next) + block->next->prev = NULL; else - { - int base_reg = 0, index_reg = 0; + mem_flush_write_page(block->phys, 0); + } + if (!block->page_mask2) { + if (block->prev_2 || block->next_2) + fatal("Invalid block_2\n"); + return; + } - switch (cpu_rm) - { - case 0: case 1: case 7: - base_reg = LOAD_REG_W(REG_BX); - break; - case 2: case 3: case 6: - base_reg = LOAD_REG_W(REG_BP); - break; - case 4: - base_reg = LOAD_REG_W(REG_SI); - break; - case 5: - base_reg = LOAD_REG_W(REG_DI); - break; - } - if (!(cpu_rm & 4)) - { - if (cpu_rm & 1) - index_reg = LOAD_REG_W(REG_DI); - else - index_reg = LOAD_REG_W(REG_SI); - } - base_reg &= 7; - index_reg &= 7; - - switch (cpu_mod) - { - case 0: - if (cpu_rm & 4) - { - addbyte(0x41); /*MOVZX EAX, base_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xc0 | base_reg); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3)); - } - } - break; - case 1: - if (cpu_rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte((fetchdat >> 8) & 0xff); - } - (*op_pc)++; - break; - case 2: - if (cpu_rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong((fetchdat >> 8) & 0xffff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3)); - addlong((fetchdat >> 8) & 0xffff); - } - (*op_pc) += 2; - break; - - } - if (cpu_mod || !(cpu_rm & 4)) - { - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - } - addbyte(0x89); /*MOV eaaddr, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - } - return op_ea_seg; + if (block->prev_2) { + block->prev_2->next_2 = block->next_2; + if (block->next_2) + block->next_2->prev_2 = block->prev_2; + } else { + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; + if (block->next_2) + block->next_2->prev_2 = NULL; + else + mem_flush_write_page(block->phys_2, 0); + } } -//#if 0 -static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) + +static void +delete_block(codeblock_t *block) { - uint32_t new_eaaddr; + uint32_t old_pc = block->pc; - if (cpu_rm == 4) - { - uint8_t sib = fetchdat >> 8; - int base_reg = -1, index_reg = -1; + if (block == codeblock_hash[HASH(block->phys)]) + codeblock_hash[HASH(block->phys)] = NULL; + if (block->valid == 0) + fatal("Deleting deleted block\n"); + block->valid = 0; + + codeblock_tree_delete(block); + remove_from_block_list(block, old_pc); +} + +void +codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) +{ + struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; + + while (block) { + if (mask & block->page_mask) { + delete_block(block); + } + if (block == block->next) + fatal("Broken 1\n"); + block = block->next; + } + + block = page->block_2[(phys_addr >> 10) & 3]; + + while (block) { + if (mask & block->page_mask2) { + delete_block(block); + } + if (block == block->next_2) + fatal("Broken 2\n"); + block = block->next_2; + } +} + +void +codegen_block_init(uint32_t phys_addr) +{ + codeblock_t *block; + page_t *page = &pages[phys_addr >> 12]; + + if (!page->block[(phys_addr >> 10) & 3]) + mem_flush_write_page(phys_addr, cs + cpu_state.pc); + + block_current = (block_current + 1) & BLOCK_MASK; + block = &codeblock[block_current]; + + if (block->valid != 0) { + delete_block(block); + } + block_num = HASH(phys_addr); + codeblock_hash[block_num] = &codeblock[block_current]; + + block->valid = 1; + block->ins = 0; + block->pc = cs + cpu_state.pc; + block->_cs = cs; + block->pnt = block_current; + block->phys = phys_addr; + block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + block->dirty_mask2 = NULL; + block->next = block->prev = NULL; + block->next_2 = block->prev_2 = NULL; + block->page_mask = 0; + block->flags = 0; + block->status = cpu_cur_status; + + block->was_recompiled = 0; + + recomp_page = block->phys & ~0xfff; + + codeblock_tree_add(block); +} + +void +codegen_block_start_recompile(codeblock_t *block) +{ + page_t *page = &pages[block->phys >> 12]; + uintptr_t rip_rel; + + if (!page->block[(block->phys >> 10) & 3]) + mem_flush_write_page(block->phys, cs + cpu_state.pc); + + block_num = HASH(block->phys); + block_current = block->pnt; + + if (block->pc != cs + cpu_state.pc || block->was_recompiled) + fatal("Recompile to used block!\n"); + + block->status = cpu_cur_status; + + block_pos = BLOCK_GPF_OFFSET; +# ifdef OLD_GPF +# if _WIN64 + addbyte(0x48); /*XOR RCX, RCX*/ + addbyte(0x31); + addbyte(0xc9); + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); +# else + addbyte(0x48); /*XOR RDI, RDI*/ + addbyte(0x31); + addbyte(0xff); + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); +# endif + call(block, (uintptr_t) x86gpf); + while (block_pos < BLOCK_EXIT_OFFSET) + addbyte(0x90); /*NOP*/ +# else + addbyte(0xC6); /*MOVB ABRT_GPF,(abrt)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(ABRT_GPF); + addbyte(0x31); /* xor eax,eax */ + addbyte(0xc0); + addbyte(0x89); /*MOVB eax,(abrt_error)*/ + addbyte(0x85); + rip_rel = ((uintptr_t) &cpu_state) + 128; + rip_rel = ((uintptr_t) & (abrt_error)) - rip_rel; + addlong((uint32_t) rip_rel); +# endif + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + addbyte(0x48); /*ADDL $40,%rsp*/ + addbyte(0x83); + addbyte(0xC4); + addbyte(0x28); + addbyte(0x41); /*POP R15*/ + addbyte(0x5f); + addbyte(0x41); /*POP R14*/ + addbyte(0x5e); + addbyte(0x41); /*POP R13*/ + addbyte(0x5d); + addbyte(0x41); /*POP R12*/ + addbyte(0x5c); + addbyte(0x5f); /*POP RDI*/ + addbyte(0x5e); /*POP RSI*/ + addbyte(0x5d); /*POP RBP*/ + addbyte(0x5b); /*POP RDX*/ + addbyte(0xC3); /*RET*/ + cpu_block_end = 0; + block_pos = 0; /*Entry code*/ + addbyte(0x53); /*PUSH RBX*/ + addbyte(0x55); /*PUSH RBP*/ + addbyte(0x56); /*PUSH RSI*/ + addbyte(0x57); /*PUSH RDI*/ + addbyte(0x41); /*PUSH R12*/ + addbyte(0x54); + addbyte(0x41); /*PUSH R13*/ + addbyte(0x55); + addbyte(0x41); /*PUSH R14*/ + addbyte(0x56); + addbyte(0x41); /*PUSH R15*/ + addbyte(0x57); + addbyte(0x48); /*SUBL $40,%rsp*/ + addbyte(0x83); + addbyte(0xEC); + addbyte(0x28); + addbyte(0x48); /*MOVL RBP, &cpu_state*/ + addbyte(0xBD); + addquad(((uintptr_t) &cpu_state) + 128); + + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; + + codegen_block_cycles = 0; + codegen_timing_block_start(); + + codegen_block_ins = 0; + codegen_block_full_ins = 0; + + recomp_page = block->phys & ~0xfff; + + codegen_flags_changed = 0; + codegen_fpu_entered = 0; + codegen_mmx_entered = 0; + + codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; + + codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; + + block->was_recompiled = 1; + + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); +} + +void +codegen_block_remove(void) +{ + codeblock_t *block = &codeblock[block_current]; + + delete_block(block); + + recomp_page = -1; +} + +void +codegen_block_generate_end_mask(void) +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t start_pc; + uint32_t end_pc; + + block->endpc = codegen_endpc; + + block->page_mask = 0; + start_pc = (block->pc & 0x3ff) & ~15; + if ((block->pc ^ block->endpc) & ~0x3ff) + end_pc = 0x3ff & ~15; + else + end_pc = (block->endpc & 0x3ff) & ~15; + if (end_pc < start_pc) + end_pc = 0x3ff; + start_pc >>= PAGE_MASK_SHIFT; + end_pc >>= PAGE_MASK_SHIFT; + + for (; start_pc <= end_pc; start_pc++) + block->page_mask |= ((uint64_t) 1 << start_pc); + + pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; + + block->phys_2 = -1; + block->page_mask2 = 0; + block->next_2 = block->prev_2 = NULL; + if ((block->pc ^ block->endpc) & ~0x3ff) { + block->phys_2 = get_phys_noabrt(block->endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; + + start_pc = 0; + end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; + for (; start_pc <= end_pc; start_pc++) + block->page_mask2 |= ((uint64_t) 1 << start_pc); + page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; + + if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) + mem_flush_write_page(block->phys_2, block->endpc); + + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + if (block->next_2->valid == 0) + fatal("block->next_2->valid=0 %p\n", (void *) block->next_2); + } + + block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + } + } + + recomp_page = -1; +} + +void +codegen_block_end(void) +{ + codeblock_t *block = &codeblock[block_current]; + + codegen_block_generate_end_mask(); + add_to_block_list(block); +} + +void +codegen_block_end_recompile(codeblock_t *block) +{ + codegen_timing_block_end(); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + + codegen_accumulate_flush(); + + addbyte(0x48); /*ADDL $40,%rsp*/ + addbyte(0x83); + addbyte(0xC4); + addbyte(0x28); + addbyte(0x41); /*POP R15*/ + addbyte(0x5f); + addbyte(0x41); /*POP R14*/ + addbyte(0x5e); + addbyte(0x41); /*POP R13*/ + addbyte(0x5d); + addbyte(0x41); /*POP R12*/ + addbyte(0x5c); + addbyte(0x5f); /*POP RDI*/ + addbyte(0x5e); /*POP RSI*/ + addbyte(0x5d); /*POP RBP*/ + addbyte(0x5b); /*POP RDX*/ + addbyte(0xC3); /*RET*/ + + if (block_pos > BLOCK_GPF_OFFSET) + fatal("Over limit!\n"); + + remove_from_block_list(block, block->pc); + block->next = block->prev = NULL; + block->next_2 = block->prev_2 = NULL; + codegen_block_generate_end_mask(); + add_to_block_list(block); +} + +void +codegen_flush(void) +{ + return; +} + +static int opcode_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ + + 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ +}; +int opcode_0f_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ + + 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ + 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ +}; + +void +codegen_debug(void) +{ +} + +static x86seg * +codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +{ + if (!cpu_mod && cpu_rm == 6) { + addbyte(0xC7); /*MOVL $0,(ssegs)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + addlong((fetchdat >> 8) & 0xffff); + (*op_pc) += 2; + } else { + int base_reg = 0, index_reg = 0; + + switch (cpu_rm) { + case 0: + case 1: + case 7: + base_reg = LOAD_REG_W(REG_BX); + break; + case 2: + case 3: + case 6: + base_reg = LOAD_REG_W(REG_BP); + break; + case 4: + base_reg = LOAD_REG_W(REG_SI); + break; + case 5: + base_reg = LOAD_REG_W(REG_DI); + break; + } + if (!(cpu_rm & 4)) { + if (cpu_rm & 1) + index_reg = LOAD_REG_W(REG_DI); + else + index_reg = LOAD_REG_W(REG_SI); + } + base_reg &= 7; + index_reg &= 7; + + switch (cpu_mod) { + case 0: + if (cpu_rm & 4) { + addbyte(0x41); /*MOVZX EAX, base_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xc0 | base_reg); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ + addbyte(0x43); + addbyte(0x8d); + if (base_reg == 5) { + addbyte(0x44); + addbyte(base_reg | (index_reg << 3)); + addbyte(0); + } else { + addbyte(0x04); + addbyte(base_reg | (index_reg << 3)); + } + } + break; + case 1: + if (cpu_rm & 4) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x40 | base_reg); + addbyte((fetchdat >> 8) & 0xff); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x44); + addbyte(base_reg | (index_reg << 3)); + addbyte((fetchdat >> 8) & 0xff); + } (*op_pc)++; - - if (cpu_mod || (sib & 7) != 5) - base_reg = LOAD_REG_L(sib & 7) & 7; - - if (((sib >> 3) & 7) != 4) - index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; - - if (index_reg == -1) - { - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOV EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x44); /*MOV EAX, base_reg*/ - addbyte(0x89); - addbyte(0xc0 | (base_reg << 3)); - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x44); - addbyte(0x24); - } - else - { - addbyte(0x40 | base_reg); - } - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x84); - addbyte(0x24); - } - else - { - addbyte(0x80 | base_reg); - } - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } + break; + case 2: + if (cpu_rm & 4) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | base_reg); + addlong((fetchdat >> 8) & 0xffff); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x84); + addbyte(base_reg | (index_reg << 3)); + addlong((fetchdat >> 8) & 0xffff); } - else - { - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - if (sib >> 6) - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ - addbyte(0x42); - addbyte(0x8d); - addbyte(0x04); - addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); - addlong(new_eaaddr); - } - else - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | index_reg); - addlong(new_eaaddr); - } - (*op_pc) += 4; - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - } - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - - addbyte(0x89); /*MOV eaaddr, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); + (*op_pc) += 2; + break; } - else - { - int base_reg; + if (cpu_mod || !(cpu_rm & 4)) { + addbyte(0x25); /*ANDL $0xffff, %eax*/ + addlong(0xffff); + } + addbyte(0x89); /*MOV eaaddr, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); - if (!cpu_mod && cpu_rm == 5) - { + if (mod1seg[cpu_rm] == &ss && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } + return op_ea_seg; +} +// #if 0 +static x86seg * +codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +{ + uint32_t new_eaaddr; + + if (cpu_rm == 4) { + uint8_t sib = fetchdat >> 8; + int base_reg = -1, index_reg = -1; + + (*op_pc)++; + + if (cpu_mod || (sib & 7) != 5) + base_reg = LOAD_REG_L(sib & 7) & 7; + + if (((sib >> 3) & 7) != 4) + index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; + + if (index_reg == -1) { + switch (cpu_mod) { + case 0: + if ((sib & 7) == 5) { new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); + addbyte(0xb8); /*MOV EAX, imm32*/ addlong(new_eaaddr); (*op_pc) += 4; - return op_ea_seg; - } - base_reg = LOAD_REG_L(cpu_rm) & 7; - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (cpu_mod == 1) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, base_reg+imm32*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong(new_eaaddr); - (*op_pc) += 4; - } - addbyte(0x89); /*MOV eaaddr, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - } - else - { - addbyte(0x44); /*MOV eaaddr, base_reg*/ + } else { + addbyte(0x44); /*MOV EAX, base_reg*/ addbyte(0x89); - addbyte(0x45 | (base_reg << 3)); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - } + addbyte(0xc0 | (base_reg << 3)); + } + break; + case 1: + addbyte(0x67); /*LEA EAX, imm8+base_reg*/ + addbyte(0x41); + addbyte(0x8d); + if (base_reg == 4) { + addbyte(0x44); + addbyte(0x24); + } else { + addbyte(0x40 | base_reg); + } + addbyte((fetchdat >> 16) & 0xff); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, imm32+base_reg*/ + addbyte(0x41); + addbyte(0x8d); + if (base_reg == 4) { + addbyte(0x84); + addbyte(0x24); + } else { + addbyte(0x80 | base_reg); + } + addlong(new_eaaddr); + (*op_pc) += 4; + break; + } + } else { + switch (cpu_mod) { + case 0: + if ((sib & 7) == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + if (sib >> 6) { + addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ + addbyte(0x42); + addbyte(0x8d); + addbyte(0x04); + addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); + addlong(new_eaaddr); + } else { + addbyte(0x67); /*LEA EAX, imm32+index_reg*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | index_reg); + addlong(new_eaaddr); + } + (*op_pc) += 4; + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + if (base_reg == 5) { + addbyte(0x44); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addbyte(0); + } else { + addbyte(0x04); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + } + } + break; + case 1: + addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x44); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addbyte((fetchdat >> 16) & 0xff); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x84); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addlong(new_eaaddr); + (*op_pc) += 4; + break; + } } - return op_ea_seg; -} -//#endif -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t op_32 = use32; - uint32_t op_pc = new_pc; - const OpFn *op_table = (OpFn *) x86_dynarec_opcodes; - RecompOpFn *recomp_op_table = recomp_opcodes; - int opcode_shift = 0; - int opcode_mask = 0x3ff; - int over = 0; - int pc_off = 0; - int test_modrm = 1; - int c; - - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 0; - op_old_pc = old_pc; - - for (c = 0; c < NR_HOST_REGS; c++) - host_reg_mapping[c] = -1; - for (c = 0; c < NR_HOST_XMM_REGS; c++) - host_reg_xmm_mapping[c] = -1; - - codegen_timing_start(); - - while (!over) + if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ { - switch (opcode) - { - case 0x0f: - op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; - - case 0x26: /*ES:*/ - op_ea_seg = &cpu_state.seg_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &cpu_state.seg_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &cpu_state.seg_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &cpu_state.seg_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &cpu_state.seg_gs; - op_ssegs = 1; - break; - - case 0x66: /*Data size select*/ - op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); - break; - case 0x67: /*Address size select*/ - op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); - break; - - case 0xd8: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; - recomp_op_table = recomp_opcodes_d8; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xd9: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; - recomp_op_table = recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; - recomp_op_table = recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; - recomp_op_table = recomp_opcodes_dc; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdd: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; - recomp_op_table = recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; - recomp_op_table = recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; - recomp_op_table = recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - - case 0xf0: /*LOCK*/ - break; - - case 0xf2: /*REPNE*/ - op_table = x86_dynarec_opcodes_REPNE; - recomp_op_table = recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ - op_table = x86_dynarec_opcodes_REPE; - recomp_op_table = recomp_opcodes_REPE; - break; - - default: - goto generate_call; - } - fetchdat = fastreadl(cs + op_pc); - codegen_timing_prefix(opcode, fetchdat); - if (cpu_state.abrt) - return; - opcode = fetchdat & 0xff; - if (!pc_off) - fetchdat >>= 8; - op_pc++; + addbyte(0x05); + addlong(stack_offset); } + if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + + addbyte(0x89); /*MOV eaaddr, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + } else { + int base_reg; + + if (!cpu_mod && cpu_rm == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + addlong(new_eaaddr); + (*op_pc) += 4; + return op_ea_seg; + } + base_reg = LOAD_REG_L(cpu_rm) & 7; + if (cpu_mod) { + if (cpu_rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (cpu_mod == 1) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x40 | base_reg); + addbyte((fetchdat >> 8) & 0xff); + (*op_pc)++; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, base_reg+imm32*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | base_reg); + addlong(new_eaaddr); + (*op_pc) += 4; + } + addbyte(0x89); /*MOV eaaddr, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + } else { + addbyte(0x44); /*MOV eaaddr, base_reg*/ + addbyte(0x89); + addbyte(0x45 | (base_reg << 3)); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + } + } + return op_ea_seg; +} +// #endif +void +codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t op_32 = use32; + uint32_t op_pc = new_pc; + const OpFn *op_table = (OpFn *) x86_dynarec_opcodes; + RecompOpFn *recomp_op_table = recomp_opcodes; + int opcode_shift = 0; + int opcode_mask = 0x3ff; + int over = 0; + int pc_off = 0; + int test_modrm = 1; + int c; + + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 0; + op_old_pc = old_pc; + + for (c = 0; c < NR_HOST_REGS; c++) + host_reg_mapping[c] = -1; + for (c = 0; c < NR_HOST_XMM_REGS; c++) + host_reg_xmm_mapping[c] = -1; + + codegen_timing_start(); + + while (!over) { + switch (opcode) { + case 0x0f: + op_table = x86_dynarec_opcodes_0f; + recomp_op_table = recomp_opcodes_0f; + over = 1; + break; + + case 0x26: /*ES:*/ + op_ea_seg = &cpu_state.seg_es; + op_ssegs = 1; + break; + case 0x2e: /*CS:*/ + op_ea_seg = &cpu_state.seg_cs; + op_ssegs = 1; + break; + case 0x36: /*SS:*/ + op_ea_seg = &cpu_state.seg_ss; + op_ssegs = 1; + break; + case 0x3e: /*DS:*/ + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 1; + break; + case 0x64: /*FS:*/ + op_ea_seg = &cpu_state.seg_fs; + op_ssegs = 1; + break; + case 0x65: /*GS:*/ + op_ea_seg = &cpu_state.seg_gs; + op_ssegs = 1; + break; + + case 0x66: /*Data size select*/ + op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); + break; + case 0x67: /*Address size select*/ + op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); + break; + + case 0xd8: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; + recomp_op_table = recomp_opcodes_d8; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xd9: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; + recomp_op_table = recomp_opcodes_d9; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xda: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; + recomp_op_table = recomp_opcodes_da; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdb: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; + recomp_op_table = recomp_opcodes_db; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdc: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; + recomp_op_table = recomp_opcodes_dc; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdd: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; + recomp_op_table = recomp_opcodes_dd; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xde: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; + recomp_op_table = recomp_opcodes_de; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdf: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; + recomp_op_table = recomp_opcodes_df; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + + case 0xf0: /*LOCK*/ + break; + + case 0xf2: /*REPNE*/ + op_table = x86_dynarec_opcodes_REPNE; + recomp_op_table = recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ + op_table = x86_dynarec_opcodes_REPE; + recomp_op_table = recomp_opcodes_REPE; + break; + + default: + goto generate_call; + } + fetchdat = fastreadl(cs + op_pc); + codegen_timing_prefix(opcode, fetchdat); + if (cpu_state.abrt) + return; + opcode = fetchdat & 0xff; + if (!pc_off) + fetchdat >>= 8; + op_pc++; + } generate_call: - codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); + codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); - codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); - codegen_block_cycles = 0; + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + codegen_block_cycles = 0; - if ((op_table == x86_dynarec_opcodes && - ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || - (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || - (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || - (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) - { - /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with - subsequent instructions, so no cycles may have been deducted for it yet. - To prevent having zero cycle blocks (eg with a jump instruction pointing - to itself), apply the cycles that would be taken if this jump is taken, - then reverse it for subsequent instructions if the jump is not taken*/ - int jump_cycles = 0; + if ((op_table == x86_dynarec_opcodes && ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) { + /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with + subsequent instructions, so no cycles may have been deducted for it yet. + To prevent having zero cycle blocks (eg with a jump instruction pointing + to itself), apply the cycles that would be taken if this jump is taken, + then reverse it for subsequent instructions if the jump is not taken*/ + int jump_cycles = 0; - if (codegen_timing_jump_cycles != NULL) - jump_cycles = codegen_timing_jump_cycles(); - - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, -jump_cycles); - codegen_accumulate_flush(); - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, jump_cycles); - } - - if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) - { - op_table = x86_dynarec_opcodes; - recomp_op_table = recomp_opcodes; - } - - if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) - { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); - if (new_pc) - { - if (new_pc != -1) - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, new_pc); - - codegen_block_ins++; - block->ins++; - codegen_block_full_ins++; - codegen_endpc = (cs + cpu_state.pc) + 8; - -#ifdef CHECK_INT - /* Check for interrupts. */ - addbyte(0xf6); /* test byte ptr[&pic_pending],1 */ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &pic_pending); - addbyte(0x01); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4])); -#endif - - return; - } - } - - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - if (op_ssegs != last_ssegs) - { - last_ssegs = op_ssegs; - addbyte(0xC6); /*MOVB $0,(ssegs)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ssegs)); - addbyte(op_ssegs); - } - if ((!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))/* && !(op_32 & 0x200)*/) - { - int stack_offset = 0; - - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; - - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; - - addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(rm_data.rm_mod_reg_data)); - addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - - op_pc += pc_off; - if (cpu_mod != 3 && !(op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); - if (cpu_mod != 3 && (op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - op_pc -= pc_off; - } - if (op_ea_seg != last_ea_seg) - { - addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ea_seg)); - addlong((uint32_t)(uintptr_t)op_ea_seg); - } + if (codegen_timing_jump_cycles != NULL) + jump_cycles = codegen_timing_jump_cycles(); + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, -jump_cycles); codegen_accumulate_flush(); + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, jump_cycles); + } - addbyte(0xC7); /*MOVL [pc],new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc + pc_off); - addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(old_pc); - if (op_32 != last_op32) - { - last_op32 = op_32; - addbyte(0xC7); /*MOVL $use32,(op32)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(op32)); - addlong(op_32); + if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { + op_table = x86_dynarec_opcodes; + recomp_op_table = recomp_opcodes; + } + + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) { + uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); + if (new_pc) { + if (new_pc != -1) + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, new_pc); + + codegen_block_ins++; + block->ins++; + codegen_block_full_ins++; + codegen_endpc = (cs + cpu_state.pc) + 8; + +# ifdef CHECK_INT + /* Check for interrupts. */ + addbyte(0xf6); /* test byte ptr[&pic_pending],1 */ + addbyte(0x04); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &pic_pending); + addbyte(0x01); + addbyte(0x0F); + addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t) (uintptr_t) &block->data[BLOCK_EXIT_OFFSET] - (uint32_t) (uintptr_t) (&block->data[block_pos + 4])); +# endif + + return; } + } - load_param_1_32(block, fetchdat); - call(block, (uintptr_t)op); + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + if (op_ssegs != last_ssegs) { + last_ssegs = op_ssegs; + addbyte(0xC6); /*MOVB $0,(ssegs)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ssegs)); + addbyte(op_ssegs); + } + if ((!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) /* && !(op_32 & 0x200)*/) { + int stack_offset = 0; - codegen_block_ins++; + if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ + stack_offset = (op_32 & 0x100) ? 4 : 2; - block->ins++; + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; -#ifdef CHECK_INT - /* Check for interrupts. */ - addbyte(0x0a); /* or al,byte ptr[&pic_pending] */ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &pic_pending); -#endif + addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(rm_data.rm_mod_reg_data)); + addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - addbyte(0x85); /*OR %eax, %eax*/ - addbyte(0xc0); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4])); + op_pc += pc_off; + if (cpu_mod != 3 && !(op_32 & 0x200)) + op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); + if (cpu_mod != 3 && (op_32 & 0x200)) + op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); + op_pc -= pc_off; + } + if (op_ea_seg != last_ea_seg) { + addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ea_seg)); + addlong((uint32_t) (uintptr_t) op_ea_seg); + } - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_accumulate_flush(); + + addbyte(0xC7); /*MOVL [pc],new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_off); + addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(old_pc); + if (op_32 != last_op32) { + last_op32 = op_32; + addbyte(0xC7); /*MOVL $use32,(op32)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(op32)); + addlong(op_32); + } + + load_param_1_32(block, fetchdat); + call(block, (uintptr_t) op); + + codegen_block_ins++; + + block->ins++; + +# ifdef CHECK_INT + /* Check for interrupts. */ + addbyte(0x0a); /* or al,byte ptr[&pic_pending] */ + addbyte(0x04); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &pic_pending); +# endif + + addbyte(0x85); /*OR %eax, %eax*/ + addbyte(0xc0); + addbyte(0x0F); + addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t) (uintptr_t) &block->data[BLOCK_EXIT_OFFSET] - (uint32_t) (uintptr_t) (&block->data[block_pos + 4])); + + codegen_endpc = (cs + cpu_state.pc) + 8; } #endif diff --git a/src/codegen/codegen_x86-64.h b/src/codegen/codegen_x86-64.h index 1ef81ff89..91c10a9ee 100644 --- a/src/codegen/codegen_x86-64.h +++ b/src/codegen/codegen_x86-64.h @@ -1,24 +1,23 @@ -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff -#define BLOCK_START 0 +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff +#define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) #define BLOCK_EXIT_OFFSET 0x7e0 #ifdef OLD_GPF -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) +# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) #else -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 12) +# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 12) #endif #define BLOCK_MAX 1620 -enum -{ - OP_RET = 0xc3 +enum { + OP_RET = 0xc3 }; #define NR_HOST_REGS 4 diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index 492328e17..61b473fe7 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -38,2139 +38,2127 @@ */ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> -#include "x86.h" -#include "x86_flags.h" -#include "x86_ops.h" -#include "x87.h" +# include +# include +# include +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> +# include "x86.h" +# include "x86_flags.h" +# include "x86_ops.h" +# include "x87.h" /*ex*/ -#include <86box/nmi.h> -#include <86box/pic.h> +# include <86box/nmi.h> +# include <86box/pic.h> -#include "386_common.h" +# include "386_common.h" -#include "codegen.h" -#include "codegen_accumulate.h" -#include "codegen_ops.h" -#include "codegen_ops_x86.h" +# include "codegen.h" +# include "codegen_accumulate.h" +# include "codegen_ops.h" +# include "codegen_ops_x86.h" -#ifdef __unix__ -#include -#include -#endif -#if defined _WIN32 -#include -#endif +# ifdef __unix__ +# include +# include +# endif +# if defined _WIN32 +# include +# endif -int codegen_flat_ds, codegen_flat_ss; -int mmx_ebx_ecx_loaded; -int codegen_flags_changed = 0; -int codegen_fpu_entered = 0; -int codegen_mmx_entered = 0; -int codegen_fpu_loaded_iq[8]; -x86seg *op_ea_seg; -int op_ssegs; +int codegen_flat_ds, codegen_flat_ss; +int mmx_ebx_ecx_loaded; +int codegen_flags_changed = 0; +int codegen_fpu_entered = 0; +int codegen_mmx_entered = 0; +int codegen_fpu_loaded_iq[8]; +x86seg *op_ea_seg; +int op_ssegs; uint32_t op_old_pc; uint32_t recomp_page = -1; -int host_reg_mapping[NR_HOST_REGS]; -int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; -codeblock_t *codeblock; +int host_reg_mapping[NR_HOST_REGS]; +int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; +codeblock_t *codeblock; codeblock_t **codeblock_hash; - -int block_current = 0; +int block_current = 0; static int block_num; -int block_pos; +int block_pos; uint32_t codegen_endpc; -int codegen_block_cycles; +int codegen_block_cycles; static int codegen_block_ins; static int codegen_block_full_ins; static uint32_t last_op32; -static x86seg *last_ea_seg; -static int last_ssegs; +static x86seg *last_ea_seg; +static int last_ssegs; static uint32_t mem_abrt_rout; -uint32_t mem_load_addr_ea_b; -uint32_t mem_load_addr_ea_w; -uint32_t mem_load_addr_ea_l; -uint32_t mem_load_addr_ea_q; -uint32_t mem_store_addr_ea_b; -uint32_t mem_store_addr_ea_w; -uint32_t mem_store_addr_ea_l; -uint32_t mem_store_addr_ea_q; -uint32_t mem_load_addr_ea_b_no_abrt; -uint32_t mem_store_addr_ea_b_no_abrt; -uint32_t mem_load_addr_ea_w_no_abrt; -uint32_t mem_store_addr_ea_w_no_abrt; -uint32_t mem_load_addr_ea_l_no_abrt; -uint32_t mem_store_addr_ea_l_no_abrt; -uint32_t mem_check_write; -uint32_t mem_check_write_w; -uint32_t mem_check_write_l; +uint32_t mem_load_addr_ea_b; +uint32_t mem_load_addr_ea_w; +uint32_t mem_load_addr_ea_l; +uint32_t mem_load_addr_ea_q; +uint32_t mem_store_addr_ea_b; +uint32_t mem_store_addr_ea_w; +uint32_t mem_store_addr_ea_l; +uint32_t mem_store_addr_ea_q; +uint32_t mem_load_addr_ea_b_no_abrt; +uint32_t mem_store_addr_ea_b_no_abrt; +uint32_t mem_load_addr_ea_w_no_abrt; +uint32_t mem_store_addr_ea_w_no_abrt; +uint32_t mem_load_addr_ea_l_no_abrt; +uint32_t mem_store_addr_ea_l_no_abrt; +uint32_t mem_check_write; +uint32_t mem_check_write_w; +uint32_t mem_check_write_l; -static uint32_t gen_MEM_LOAD_ADDR_EA_B() +static uint32_t +gen_MEM_LOAD_ADDR_EA_B(void) { - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX EAX, B[EDX+EDI]*/ - addbyte(0xb6); - addbyte(0x04); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x01); /*slowpath: ADD ESI,EAX*/ - addbyte(0xc6); - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmembl*/ - addlong((uint32_t)readmembl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*MOVZX EAX, AL*/ - addbyte(0xb6); - addbyte(0xc0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_LOAD_ADDR_EA_W() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX EAX, [EDX+EDI]W*/ - addbyte(0xb7); - addbyte(0x04); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x01); /*slowpath: ADD ESI,EAX*/ - addbyte(0xc6); - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemwl*/ - addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*MOVZX EAX, AX*/ - addbyte(0xb7); - addbyte(0xc0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_LOAD_ADDR_EA_L() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ - addbyte(0x04); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x01); /*slowpath: ADD ESI,EAX*/ - addbyte(0xc6); - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemll*/ - addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_LOAD_ADDR_EA_Q() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+4+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+4+1); - addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ - addbyte(0x04); - addbyte(0x3a); - addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ - addbyte(0x54); - addbyte(0x3a); - addbyte(4); - addbyte(0xc3); /*RET*/ - - addbyte(0x01); /*slowpath: ADD ESI,EAX*/ - addbyte(0xc6); - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemql*/ - addlong((uint32_t)readmemql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_B() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x88); /*MOV [EDI+ESI],CL*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xC3); - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writemembl*/ - addlong((uint32_t)writemembl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_W() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x66); /*MOV [EDI+ESI],CX*/ - addbyte(0x89); - addbyte(0x04 | (REG_CX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xC3); - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememwl*/ - addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_L() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x89); /*MOV [EDI+ESI],ECX*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xC3); - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememll*/ - addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_Q() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = EBX/ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EDX, ESI*/ - addbyte(0xf2); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+4+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+4+1); - addbyte(0x89); /*MOV [EDI+ESI],EBX*/ - addbyte(0x04 | (REG_EBX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0x89); /*MOV 4[EDI+ESI],EBX*/ - addbyte(0x44 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(4); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0x01); /*ADD EDX,EAX*/ - addbyte(0xC2); - addbyte(0x52); /*PUSH EDX*/ - addbyte(0xe8); /*CALL writememql*/ - addlong((uint32_t)writememql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_B_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX ECX, B[EDX+EDI]*/ - addbyte(0xb6); - addbyte(0x0c); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x01); /*slowpath: ADD ESI,EAX*/ - addbyte(0xc6); - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmembl*/ - addlong((uint32_t)readmembl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); -#endif - addbyte(0x0f); /*MOVZX ECX, AL*/ - addbyte(0xb6); - addbyte(0xc8); -#ifndef RELEASE_BUILD - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_W_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX ECX, [EDX+EDI]W*/ - addbyte(0xb7); - addbyte(0x0c); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x01); /*slowpath: ADD ESI,EAX*/ - addbyte(0xc6); - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemwl*/ - addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); -#endif - addbyte(0x0f); /*MOVZX ECX, AX*/ - addbyte(0xb7); - addbyte(0xc8); -#ifndef RELEASE_BUILD - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_L_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x8b); /*MOV ECX, [EDX+EDI]*/ - addbyte(0x0c); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x01); /*slowpath: ADD ESI,EAX*/ - addbyte(0xc6); - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemll*/ - addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0x83); /*SUBL 4,%esp*/ - addbyte(0xEC); - addbyte(4); - addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_B_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x88); /*MOV [EDI+ESI],CL*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xc3); - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writemembl*/ - addlong((uint32_t)writemembl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_W_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x66); /*MOV [EDI+ESI],CX*/ - addbyte(0x89); - addbyte(0x04 | (REG_CX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xC3); - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememwl*/ - addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -#ifndef RELEASE_BUILD -static char gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_L_NO_ABRT aborted\n"; -#endif -static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x89); /*MOV [EDI+ESI],ECX*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xC3); - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememll*/ - addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - addlong((uint32_t)gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err); - addbyte(0xe8); /*CALL fatal*/ - addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - /*Should not return!*/ -#endif - return addr; -} - -static uint32_t gen_MEM_CHECK_WRITE() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*seg = ESI, addr = EAX*/ - - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3d); - addlong((uint32_t)&cr0); - addbyte(0); - addbyte(0x78); /*JS +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(11); - addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ - addbyte(0x3c); - addbyte(0xbd); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - - /*slowpath:*/ - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x6a); /*PUSH 1*/ - addbyte(1); - addbyte(0x57); /*PUSH EDI*/ - addbyte(0xe8); /*CALL mmutranslatereal32*/ - addlong((uint32_t)mmutranslatereal32 - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_CHECK_WRITE_W() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*seg = ESI, addr = EAX*/ - - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3d); - addlong((uint32_t)&cr0); - addbyte(0); - addbyte(0x78); /*JS +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x8d); /*LEA ESI, 1[EDI]*/ - addbyte(0x77); - addbyte(0x01); - addbyte(0x74); /*JE slowpath*/ - addbyte(11); - addbyte(0x89); /*MOV EAX, EDI*/ - addbyte(0xf8); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ - addbyte(0x3c); - addbyte(0xbd); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(11); - addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ - addbyte(0x3c); - addbyte(0xb5); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - - /*slowpath:*/ - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc7); - /*slowpath_lp:*/ - addbyte(0x6a); /*PUSH 1*/ - addbyte(1); - addbyte(0x57); /*PUSH EDI*/ - addbyte(0xe8); /*CALL mmutranslatereal32*/ - addlong((uint32_t)mmutranslatereal32 - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x83); /*ADD EDI, 1*/ - addbyte(0xc7); - addbyte(1); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST $fff, EDI*/ - addbyte(0xc7); - addlong(0xfff); - addbyte(0x74); /*JE slowpath_lp*/ - addbyte(-33); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_CHECK_WRITE_L() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*seg = ESI, addr = EAX*/ - - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3d); - addlong((uint32_t)&cr0); - addbyte(0); - addbyte(0x78); /*JS +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x8d); /*LEA ESI, 3[EDI]*/ - addbyte(0x77); - addbyte(0x03); - addbyte(0x74); /*JE slowpath*/ - addbyte(11); - addbyte(0x89); /*MOV EAX, EDI*/ - addbyte(0xf8); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ - addbyte(0x3c); - addbyte(0xbd); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(11); - addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ - addbyte(0x3c); - addbyte(0xb5); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - - /*slowpath:*/ - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc7); - /*slowpath_lp:*/ - addbyte(0x6a); /*PUSH 1*/ - addbyte(1); - addbyte(0x57); /*PUSH EDI*/ - addbyte(0xe8); /*CALL mmutranslatereal32*/ - addlong((uint32_t)mmutranslatereal32 - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x83); /*ADD EDI, 3*/ - addbyte(0xc7); - addbyte(3); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 2-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST EDI, FFC*/ - addbyte(0xc7); - addlong(0xffc); - addbyte(0x74); /*JE slowpath_lp*/ - addbyte(-33); - addbyte(0xc3); /*RET*/ - - return addr; -} - -void codegen_init() -{ -#ifdef _WIN32 - codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#elif defined __unix__ - codeblock = mmap(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0); -#else - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); -#endif - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - - memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - - block_current = BLOCK_SIZE; - block_pos = 0; - mem_abrt_rout = (uint32_t)&codeblock[block_current].data[block_pos]; - addbyte(0x83); /*ADDL $16+4,%esp*/ - addbyte(0xC4); - addbyte(0x10+4); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_l = (uint32_t)gen_MEM_LOAD_ADDR_EA_L(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_w = (uint32_t)gen_MEM_LOAD_ADDR_EA_W(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_b = (uint32_t)gen_MEM_LOAD_ADDR_EA_B(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_q = (uint32_t)gen_MEM_LOAD_ADDR_EA_Q(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_l = (uint32_t)gen_MEM_STORE_ADDR_EA_L(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_w = (uint32_t)gen_MEM_STORE_ADDR_EA_W(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_b = (uint32_t)gen_MEM_STORE_ADDR_EA_B(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_q = (uint32_t)gen_MEM_STORE_ADDR_EA_Q(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_b_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_b_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_B_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_w_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_w_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_W_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_l_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_l_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_L_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_check_write = (uint32_t)gen_MEM_CHECK_WRITE(); - block_pos = (block_pos + 15) & ~15; - mem_check_write_w = (uint32_t)gen_MEM_CHECK_WRITE_W(); - block_pos = (block_pos + 15) & ~15; - mem_check_write_l = (uint32_t)gen_MEM_CHECK_WRITE_L(); - -#ifndef _MSC_VER - asm( - "fstcw %0\n" - : "=m" (cpu_state.old_npxc) - ); -#else - __asm - { - fstcw cpu_state.old_npxc - } -#endif -} - -void codegen_reset() -{ - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - mem_reset_page_blocks(); -} - -void dump_block() -{ -} - -static void add_to_block_list(codeblock_t *block) -{ - codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; - - if (!block->page_mask) - fatal("add_to_block_list - mask = 0\n"); - - if (block_prev) - { - block->next = block_prev; - block_prev->prev = block; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - else - { - block->next = NULL; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - - if (block->next) - { - if (!block->next->valid) - fatal("block->next->valid=0 %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); - } - - if (block->page_mask2) - { - block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; - - if (block_prev) - { - block->next_2 = block_prev; - block_prev->prev_2 = block; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - else - { - block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - } -} - -static void remove_from_block_list(codeblock_t *block, uint32_t pc) -{ - if (!block->page_mask) - return; - - if (block->prev) - { - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } - else - { - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; - if (block->next) - block->next->prev = NULL; - else - mem_flush_write_page(block->phys, 0); - } - if (!block->page_mask2) - { - if (block->prev_2 || block->next_2) - fatal("Invalid block_2\n"); - return; - } - - if (block->prev_2) - { - block->prev_2->next_2 = block->next_2; - if (block->next_2) - block->next_2->prev_2 = block->prev_2; - } - else - { - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; - if (block->next_2) - block->next_2->prev_2 = NULL; - else - mem_flush_write_page(block->phys_2, 0); - } -} - -static void delete_block(codeblock_t *block) -{ - uint32_t old_pc = block->pc; - - if (block == codeblock_hash[HASH(block->phys)]) - codeblock_hash[HASH(block->phys)] = NULL; - - if (!block->valid) - fatal("Deleting deleted block\n"); - block->valid = 0; - - codeblock_tree_delete(block); - remove_from_block_list(block, old_pc); -} - -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) -{ - struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask) - { - delete_block(block); - } - if (block == block->next) - fatal("Broken 1\n"); - block = block->next; - } - - block = page->block_2[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask2) - { - delete_block(block); - } - if (block == block->next_2) - fatal("Broken 2\n"); - block = block->next_2; - } -} - -void codegen_block_init(uint32_t phys_addr) -{ - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; - - if (!page->block[(phys_addr >> 10) & 3]) - mem_flush_write_page(phys_addr, cs+cpu_state.pc); - - block_current = (block_current + 1) & BLOCK_MASK; - block = &codeblock[block_current]; - - if (block->valid != 0) - { - delete_block(block); - } - block_num = HASH(phys_addr); - codeblock_hash[block_num] = &codeblock[block_current]; - - block->valid = 1; - block->ins = 0; - block->pc = cs + cpu_state.pc; - block->_cs = cs; - block->pnt = block_current; - block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - block->dirty_mask2 = NULL; - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - block->page_mask = 0; - block->flags = CODEBLOCK_STATIC_TOP; - block->status = cpu_cur_status; - - block->was_recompiled = 0; - - recomp_page = block->phys & ~0xfff; - - codeblock_tree_add(block); -} - -void codegen_block_start_recompile(codeblock_t *block) -{ - page_t *page = &pages[block->phys >> 12]; - - if (!page->block[(block->phys >> 10) & 3]) - mem_flush_write_page(block->phys, cs+cpu_state.pc); - - block_num = HASH(block->phys); - block_current = block->pnt; - - if (block->pc != cs + cpu_state.pc || block->was_recompiled) - fatal("Recompile to used block!\n"); - - block->status = cpu_cur_status; - - block_pos = BLOCK_GPF_OFFSET; -#ifdef OLD_GPF - addbyte(0xc7); /*MOV [ESP],0*/ - addbyte(0x04); - addbyte(0x24); - addlong(0); - addbyte(0xc7); /*MOV [ESP+4],0*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addlong(0); - addbyte(0xe8); /*CALL x86gpf*/ - addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -#else - addbyte(0xc6); /* mov byte ptr[&(cpu_state.abrt)],ABRT_GPF */ - addbyte(0x05); - addlong((uint32_t) (uintptr_t) &(cpu_state.abrt)); - addbyte(ABRT_GPF); - addbyte(0x31); /* xor eax,eax */ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x0f); /*MOVZX EAX, B[EDX+EDI]*/ + addbyte(0xb6); + addbyte(0x04); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmembl*/ + addlong((uint32_t) readmembl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*MOVZX EAX, AL*/ + addbyte(0xb6); addbyte(0xc0); - addbyte(0xa3); /* mov [&(abrt_error)],eax */ - addlong((uint32_t) (uintptr_t) &(abrt_error)); -#endif - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x83); /*ADDL $16,%esp*/ - addbyte(0xC4); - addbyte(0x10); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - cpu_block_end = 0; - block_pos = 0; /*Entry code*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0x55); /*PUSH EBP*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0x57); /*PUSH EDI*/ - addbyte(0x83); /*SUBL $16,%esp*/ - addbyte(0xEC); - addbyte(0x10); - addbyte(0xBD); /*MOVL EBP, &cpu_state*/ - addlong(((uintptr_t)&cpu_state) + 128); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; - - codegen_block_cycles = 0; - codegen_timing_block_start(); - - codegen_block_ins = 0; - codegen_block_full_ins = 0; - - recomp_page = block->phys & ~0xfff; - - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; - - codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = - codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - - cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; - - block->TOP = cpu_state.TOP & 7; - block->was_recompiled = 1; - - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); - - codegen_accumulate_reset(); + return addr; } -void codegen_block_remove() +static uint32_t +gen_MEM_LOAD_ADDR_EA_W(void) { - codeblock_t *block = &codeblock[block_current]; + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; - delete_block(block); + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x0f); /*MOVZX EAX, [EDX+EDI]W*/ + addbyte(0xb7); + addbyte(0x04); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ - recomp_page = -1; + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemwl*/ + addlong((uint32_t) readmemwl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*MOVZX EAX, AX*/ + addbyte(0xb7); + addbyte(0xc0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; } -void codegen_block_generate_end_mask() +static uint32_t +gen_MEM_LOAD_ADDR_EA_L(void) { - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; - block->endpc = codegen_endpc; + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ + addbyte(0x04); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ - block->page_mask = 0; - start_pc = (block->pc & 0x3ff) & ~15; - if ((block->pc ^ block->endpc) & ~0x3ff) - end_pc = 0x3ff & ~15; - else - end_pc = (block->endpc & 0x3ff) & ~15; - if (end_pc < start_pc) - end_pc = 0x3ff; - start_pc >>= PAGE_MASK_SHIFT; - end_pc >>= PAGE_MASK_SHIFT; + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemll*/ + addlong((uint32_t) readmemll - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ - for (; start_pc <= end_pc; start_pc++) - { - block->page_mask |= ((uint64_t)1 << start_pc); + return addr; +} + +static uint32_t +gen_MEM_LOAD_ADDR_EA_Q(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 7*/ + addbyte(0xc7); + addlong(7); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 4 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 4 + 1); + addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ + addbyte(0x04); + addbyte(0x3a); + addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ + addbyte(0x54); + addbyte(0x3a); + addbyte(4); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemql*/ + addlong((uint32_t) readmemql - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_STORE_ADDR_EA_B(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x88); /*MOV [EDI+ESI],CL*/ + addbyte(0x04 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writemembl*/ + addlong((uint32_t) writemembl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_STORE_ADDR_EA_W(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x66); /*MOV [EDI+ESI],CX*/ + addbyte(0x89); + addbyte(0x04 | (REG_CX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememwl*/ + addlong((uint32_t) writememwl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_STORE_ADDR_EA_L(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x89); /*MOV [EDI+ESI],ECX*/ + addbyte(0x04 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememll*/ + addlong((uint32_t) writememll - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_STORE_ADDR_EA_Q(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = EBX/ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EDX, ESI*/ + addbyte(0xf2); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 7*/ + addbyte(0xc7); + addlong(7); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 4 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 4 + 1); + addbyte(0x89); /*MOV [EDI+ESI],EBX*/ + addbyte(0x04 | (REG_EBX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0x89); /*MOV 4[EDI+ESI],EBX*/ + addbyte(0x44 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(4); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x53); /*PUSH EBX*/ + addbyte(0x01); /*ADD EDX,EAX*/ + addbyte(0xC2); + addbyte(0x52); /*PUSH EDX*/ + addbyte(0xe8); /*CALL writememql*/ + addlong((uint32_t) writememql - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 12*/ + addbyte(0xc4); + addbyte(12); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_B_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x0f); /*MOVZX ECX, B[EDX+EDI]*/ + addbyte(0xb6); + addbyte(0x0c); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmembl*/ + addlong((uint32_t) readmembl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); +# endif + addbyte(0x0f); /*MOVZX ECX, AL*/ + addbyte(0xb6); + addbyte(0xc8); +# ifndef RELEASE_BUILD + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_W_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x0f); /*MOVZX ECX, [EDX+EDI]W*/ + addbyte(0xb7); + addbyte(0x0c); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemwl*/ + addlong((uint32_t) readmemwl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); +# endif + addbyte(0x0f); /*MOVZX ECX, AX*/ + addbyte(0xb7); + addbyte(0xc8); +# ifndef RELEASE_BUILD + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_L_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JE slowpath*/ + addbyte(3 + 2 + 3 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x8b); /*MOV ECX, [EDX+EDI]*/ + addbyte(0x0c); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemll*/ + addlong((uint32_t) readmemll - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc1); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0x83); /*SUBL 4,%esp*/ + addbyte(0xEC); + addbyte(4); + addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_B_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_STORE_ADDR_EA_B_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x88); /*MOV [EDI+ESI],CL*/ + addbyte(0x04 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xc3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writemembl*/ + addlong((uint32_t) writemembl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_W_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_STORE_ADDR_EA_W_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x66); /*MOV [EDI+ESI],CX*/ + addbyte(0x89); + addbyte(0x04 | (REG_CX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememwl*/ + addlong((uint32_t) writememwl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_L_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_STORE_ADDR_EA_L_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x89); /*MOV [EDI+ESI],ECX*/ + addbyte(0x04 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememll*/ + addlong((uint32_t) writememll - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +static uint32_t +gen_MEM_CHECK_WRITE(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*seg = ESI, addr = EAX*/ + + addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x3c); + addbyte(0x30); + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3d); + addlong((uint32_t) &cr0); + addbyte(0); + addbyte(0x78); /*JS +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(11); + addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ + addbyte(0x3c); + addbyte(0xbd); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + + /*slowpath:*/ + addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x3c); + addbyte(0x30); + addbyte(0x6a); /*PUSH 1*/ + addbyte(1); + addbyte(0x57); /*PUSH EDI*/ + addbyte(0xe8); /*CALL mmutranslatereal32*/ + addlong((uint32_t) mmutranslatereal32 - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_CHECK_WRITE_W(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*seg = ESI, addr = EAX*/ + + addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x3c); + addbyte(0x30); + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3d); + addlong((uint32_t) &cr0); + addbyte(0); + addbyte(0x78); /*JS +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x8d); /*LEA ESI, 1[EDI]*/ + addbyte(0x77); + addbyte(0x01); + addbyte(0x74); /*JE slowpath*/ + addbyte(11); + addbyte(0x89); /*MOV EAX, EDI*/ + addbyte(0xf8); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xee); + addbyte(12); + addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ + addbyte(0x3c); + addbyte(0xbd); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(11); + addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ + addbyte(0x3c); + addbyte(0xb5); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + + /*slowpath:*/ + addbyte(0x89); /*MOV EDI, EAX*/ + addbyte(0xc7); + /*slowpath_lp:*/ + addbyte(0x6a); /*PUSH 1*/ + addbyte(1); + addbyte(0x57); /*PUSH EDI*/ + addbyte(0xe8); /*CALL mmutranslatereal32*/ + addlong((uint32_t) mmutranslatereal32 - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x83); /*ADD EDI, 1*/ + addbyte(0xc7); + addbyte(1); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ + addbyte(0xf7); /*TEST $fff, EDI*/ + addbyte(0xc7); + addlong(0xfff); + addbyte(0x74); /*JE slowpath_lp*/ + addbyte(-33); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_CHECK_WRITE_L(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*seg = ESI, addr = EAX*/ + + addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x3c); + addbyte(0x30); + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3d); + addlong((uint32_t) &cr0); + addbyte(0); + addbyte(0x78); /*JS +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x8d); /*LEA ESI, 3[EDI]*/ + addbyte(0x77); + addbyte(0x03); + addbyte(0x74); /*JE slowpath*/ + addbyte(11); + addbyte(0x89); /*MOV EAX, EDI*/ + addbyte(0xf8); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xee); + addbyte(12); + addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ + addbyte(0x3c); + addbyte(0xbd); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(11); + addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ + addbyte(0x3c); + addbyte(0xb5); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + + /*slowpath:*/ + addbyte(0x89); /*MOV EDI, EAX*/ + addbyte(0xc7); + /*slowpath_lp:*/ + addbyte(0x6a); /*PUSH 1*/ + addbyte(1); + addbyte(0x57); /*PUSH EDI*/ + addbyte(0xe8); /*CALL mmutranslatereal32*/ + addlong((uint32_t) mmutranslatereal32 - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x83); /*ADD EDI, 3*/ + addbyte(0xc7); + addbyte(3); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + /*If bits 2-11 of the address are now 0 then this crosses a page, so loop back*/ + addbyte(0xf7); /*TEST EDI, FFC*/ + addbyte(0xc7); + addlong(0xffc); + addbyte(0x74); /*JE slowpath_lp*/ + addbyte(-33); + addbyte(0xc3); /*RET*/ + + return addr; +} + +void +codegen_init(void) +{ +# ifdef _WIN32 + codeblock = VirtualAlloc(NULL, (BLOCK_SIZE + 1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +# elif defined __unix__ + codeblock = mmap(NULL, (BLOCK_SIZE + 1) * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0); +# else + codeblock = malloc((BLOCK_SIZE + 1) * sizeof(codeblock_t)); +# endif + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + + memset(codeblock, 0, (BLOCK_SIZE + 1) * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + + block_current = BLOCK_SIZE; + block_pos = 0; + mem_abrt_rout = (uint32_t) &codeblock[block_current].data[block_pos]; + addbyte(0x83); /*ADDL $16+4,%esp*/ + addbyte(0xC4); + addbyte(0x10 + 4); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_l = (uint32_t) gen_MEM_LOAD_ADDR_EA_L(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_w = (uint32_t) gen_MEM_LOAD_ADDR_EA_W(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_b = (uint32_t) gen_MEM_LOAD_ADDR_EA_B(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_q = (uint32_t) gen_MEM_LOAD_ADDR_EA_Q(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_l = (uint32_t) gen_MEM_STORE_ADDR_EA_L(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_w = (uint32_t) gen_MEM_STORE_ADDR_EA_W(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_b = (uint32_t) gen_MEM_STORE_ADDR_EA_B(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_q = (uint32_t) gen_MEM_STORE_ADDR_EA_Q(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_b_no_abrt = (uint32_t) gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_b_no_abrt = (uint32_t) gen_MEM_STORE_ADDR_EA_B_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_w_no_abrt = (uint32_t) gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_w_no_abrt = (uint32_t) gen_MEM_STORE_ADDR_EA_W_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_l_no_abrt = (uint32_t) gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_l_no_abrt = (uint32_t) gen_MEM_STORE_ADDR_EA_L_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_check_write = (uint32_t) gen_MEM_CHECK_WRITE(); + block_pos = (block_pos + 15) & ~15; + mem_check_write_w = (uint32_t) gen_MEM_CHECK_WRITE_W(); + block_pos = (block_pos + 15) & ~15; + mem_check_write_l = (uint32_t) gen_MEM_CHECK_WRITE_L(); + +# ifndef _MSC_VER + asm( + "fstcw %0\n" + : "=m"(cpu_state.old_npxc)); +# else + __asm + { + fstcw cpu_state.old_npxc + } +# endif +} + +void +codegen_reset(void) +{ + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + mem_reset_page_blocks(); +} + +void +dump_block(void) +{ +} + +static void +add_to_block_list(codeblock_t *block) +{ + codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; + + if (!block->page_mask) + fatal("add_to_block_list - mask = 0\n"); + + if (block_prev) { + block->next = block_prev; + block_prev->prev = block; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } else { + block->next = NULL; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } + + if (block->next) { + if (!block->next->valid) + fatal("block->next->valid=0 %p %p %x %x\n", (void *) block->next, (void *) codeblock, block_current, block_pos); + } + + if (block->page_mask2) { + block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; + + if (block_prev) { + block->next_2 = block_prev; + block_prev->prev_2 = block; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; + } else { + block->next_2 = NULL; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; } - - pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; - - block->phys_2 = -1; - block->page_mask2 = 0; - block->next_2 = block->prev_2 = NULL; - if ((block->pc ^ block->endpc) & ~0x3ff) - { - block->phys_2 = get_phys_noabrt(block->endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; - - start_pc = 0; - end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; - for (; start_pc <= end_pc; start_pc++) - block->page_mask2 |= ((uint64_t)1 << start_pc); - page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; - - if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) - mem_flush_write_page(block->phys_2, block->endpc); - - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (!block->next_2->valid) - fatal("block->next_2->valid=0 %p\n", (void *)block->next_2); - } - - block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - } - } - - recomp_page = -1; + } } -void codegen_block_end() -{ - codeblock_t *block = &codeblock[block_current]; - - codegen_block_generate_end_mask(); - add_to_block_list(block); -} - -void codegen_block_end_recompile(codeblock_t *block) -{ - codegen_timing_block_end(); - codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); - - codegen_accumulate_flush(); - - addbyte(0x83); /*ADDL $16,%esp*/ - addbyte(0xC4); - addbyte(0x10); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - - if (block_pos > BLOCK_GPF_OFFSET) - fatal("Over limit!\n"); - - remove_from_block_list(block, block->pc); - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - codegen_block_generate_end_mask(); - add_to_block_list(block); - - if (!(block->flags & CODEBLOCK_HAS_FPU)) - block->flags &= ~CODEBLOCK_STATIC_TOP; -} - -void codegen_flush() +static void +remove_from_block_list(codeblock_t *block, uint32_t pc) { + if (!block->page_mask) return; -} -static int opcode_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ - - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ -}; -int opcode_0f_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ - - 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ - 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ -}; - -void codegen_debug() -{ -} - -static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) -{ - if (!cpu_mod && cpu_rm == 6) - { - addbyte(0xC7); /*MOVL $0,(ssegs)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } + if (block->prev) { + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } else { + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; + if (block->next) + block->next->prev = NULL; else - { - switch (cpu_mod) - { - case 0: - addbyte(0xa1); /*MOVL *mod1add[0][cpu_rm], %eax*/ - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - break; - case 1: - addbyte(0xb8); /*MOVL ,%eax*/ - addlong((uint32_t)(int8_t)(rmdat >> 8)); - addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - (*op_pc)++; - break; - case 2: - addbyte(0xb8); /*MOVL ,%eax*/ - addlong((fetchdat >> 8) & 0xffff); - addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - (*op_pc) += 2; - break; - } - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); + mem_flush_write_page(block->phys, 0); + } + if (!block->page_mask2) { + if (block->prev_2 || block->next_2) + fatal("Invalid block_2\n"); + return; + } - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - } - return op_ea_seg; + if (block->prev_2) { + block->prev_2->next_2 = block->next_2; + if (block->next_2) + block->next_2->prev_2 = block->prev_2; + } else { + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; + if (block->next_2) + block->next_2->prev_2 = NULL; + else + mem_flush_write_page(block->phys_2, 0); + } } -static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +static void +delete_block(codeblock_t *block) { - uint32_t new_eaaddr; + uint32_t old_pc = block->pc; - if (cpu_rm == 4) - { - uint8_t sib = fetchdat >> 8; + if (block == codeblock_hash[HASH(block->phys)]) + codeblock_hash[HASH(block->phys)] = NULL; + + if (!block->valid) + fatal("Deleting deleted block\n"); + block->valid = 0; + + codeblock_tree_delete(block); + remove_from_block_list(block, old_pc); +} + +void +codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) +{ + struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; + + while (block) { + if (mask & block->page_mask) { + delete_block(block); + } + if (block == block->next) + fatal("Broken 1\n"); + block = block->next; + } + + block = page->block_2[(phys_addr >> 10) & 3]; + + while (block) { + if (mask & block->page_mask2) { + delete_block(block); + } + if (block == block->next_2) + fatal("Broken 2\n"); + block = block->next_2; + } +} + +void +codegen_block_init(uint32_t phys_addr) +{ + codeblock_t *block; + page_t *page = &pages[phys_addr >> 12]; + + if (!page->block[(phys_addr >> 10) & 3]) + mem_flush_write_page(phys_addr, cs + cpu_state.pc); + + block_current = (block_current + 1) & BLOCK_MASK; + block = &codeblock[block_current]; + + if (block->valid != 0) { + delete_block(block); + } + block_num = HASH(phys_addr); + codeblock_hash[block_num] = &codeblock[block_current]; + + block->valid = 1; + block->ins = 0; + block->pc = cs + cpu_state.pc; + block->_cs = cs; + block->pnt = block_current; + block->phys = phys_addr; + block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + block->dirty_mask2 = NULL; + block->next = block->prev = NULL; + block->next_2 = block->prev_2 = NULL; + block->page_mask = 0; + block->flags = CODEBLOCK_STATIC_TOP; + block->status = cpu_cur_status; + + block->was_recompiled = 0; + + recomp_page = block->phys & ~0xfff; + + codeblock_tree_add(block); +} + +void +codegen_block_start_recompile(codeblock_t *block) +{ + page_t *page = &pages[block->phys >> 12]; + + if (!page->block[(block->phys >> 10) & 3]) + mem_flush_write_page(block->phys, cs + cpu_state.pc); + + block_num = HASH(block->phys); + block_current = block->pnt; + + if (block->pc != cs + cpu_state.pc || block->was_recompiled) + fatal("Recompile to used block!\n"); + + block->status = cpu_cur_status; + + block_pos = BLOCK_GPF_OFFSET; +# ifdef OLD_GPF + addbyte(0xc7); /*MOV [ESP],0*/ + addbyte(0x04); + addbyte(0x24); + addlong(0); + addbyte(0xc7); /*MOV [ESP+4],0*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x04); + addlong(0); + addbyte(0xe8); /*CALL x86gpf*/ + addlong((uint32_t) x86gpf - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +# else + addbyte(0xc6); /* mov byte ptr[&(cpu_state.abrt)],ABRT_GPF */ + addbyte(0x05); + addlong((uint32_t) (uintptr_t) & (cpu_state.abrt)); + addbyte(ABRT_GPF); + addbyte(0x31); /* xor eax,eax */ + addbyte(0xc0); + addbyte(0xa3); /* mov [&(abrt_error)],eax */ + addlong((uint32_t) (uintptr_t) & (abrt_error)); +# endif + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + addbyte(0x83); /*ADDL $16,%esp*/ + addbyte(0xC4); + addbyte(0x10); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ + cpu_block_end = 0; + block_pos = 0; /*Entry code*/ + addbyte(0x53); /*PUSH EBX*/ + addbyte(0x55); /*PUSH EBP*/ + addbyte(0x56); /*PUSH ESI*/ + addbyte(0x57); /*PUSH EDI*/ + addbyte(0x83); /*SUBL $16,%esp*/ + addbyte(0xEC); + addbyte(0x10); + addbyte(0xBD); /*MOVL EBP, &cpu_state*/ + addlong(((uintptr_t) &cpu_state) + 128); + + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; + + codegen_block_cycles = 0; + codegen_timing_block_start(); + + codegen_block_ins = 0; + codegen_block_full_ins = 0; + + recomp_page = block->phys & ~0xfff; + + codegen_flags_changed = 0; + codegen_fpu_entered = 0; + codegen_mmx_entered = 0; + + codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; + + block->TOP = cpu_state.TOP & 7; + block->was_recompiled = 1; + + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); + + codegen_accumulate_reset(); +} + +void +codegen_block_remove(void) +{ + codeblock_t *block = &codeblock[block_current]; + + delete_block(block); + + recomp_page = -1; +} + +void +codegen_block_generate_end_mask(void) +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t start_pc; + uint32_t end_pc; + + block->endpc = codegen_endpc; + + block->page_mask = 0; + start_pc = (block->pc & 0x3ff) & ~15; + if ((block->pc ^ block->endpc) & ~0x3ff) + end_pc = 0x3ff & ~15; + else + end_pc = (block->endpc & 0x3ff) & ~15; + if (end_pc < start_pc) + end_pc = 0x3ff; + start_pc >>= PAGE_MASK_SHIFT; + end_pc >>= PAGE_MASK_SHIFT; + + for (; start_pc <= end_pc; start_pc++) { + block->page_mask |= ((uint64_t) 1 << start_pc); + } + + pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; + + block->phys_2 = -1; + block->page_mask2 = 0; + block->next_2 = block->prev_2 = NULL; + if ((block->pc ^ block->endpc) & ~0x3ff) { + block->phys_2 = get_phys_noabrt(block->endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; + + start_pc = 0; + end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; + for (; start_pc <= end_pc; start_pc++) + block->page_mask2 |= ((uint64_t) 1 << start_pc); + page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; + + if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) + mem_flush_write_page(block->phys_2, block->endpc); + + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + if (!block->next_2->valid) + fatal("block->next_2->valid=0 %p\n", (void *) block->next_2); + } + + block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + } + } + + recomp_page = -1; +} + +void +codegen_block_end(void) +{ + codeblock_t *block = &codeblock[block_current]; + + codegen_block_generate_end_mask(); + add_to_block_list(block); +} + +void +codegen_block_end_recompile(codeblock_t *block) +{ + codegen_timing_block_end(); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + + codegen_accumulate_flush(); + + addbyte(0x83); /*ADDL $16,%esp*/ + addbyte(0xC4); + addbyte(0x10); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ + + if (block_pos > BLOCK_GPF_OFFSET) + fatal("Over limit!\n"); + + remove_from_block_list(block, block->pc); + block->next = block->prev = NULL; + block->next_2 = block->prev_2 = NULL; + codegen_block_generate_end_mask(); + add_to_block_list(block); + + if (!(block->flags & CODEBLOCK_HAS_FPU)) + block->flags &= ~CODEBLOCK_STATIC_TOP; +} + +void +codegen_flush(void) +{ + return; +} + +static int opcode_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ + + 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ +}; +int opcode_0f_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ + + 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ + 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ +}; + +void +codegen_debug(void) +{ +} + +static x86seg * +codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +{ + if (!cpu_mod && cpu_rm == 6) { + addbyte(0xC7); /*MOVL $0,(ssegs)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + addlong((fetchdat >> 8) & 0xffff); + (*op_pc) += 2; + } else { + switch (cpu_mod) { + case 0: + addbyte(0xa1); /*MOVL *mod1add[0][cpu_rm], %eax*/ + addlong((uint32_t) mod1add[0][cpu_rm]); + addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][cpu_rm]); + break; + case 1: + addbyte(0xb8); /*MOVL ,%eax*/ + addlong((uint32_t) (int8_t) (rmdat >> 8)); + addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[0][cpu_rm]); + addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][cpu_rm]); (*op_pc)++; + break; + case 2: + addbyte(0xb8); /*MOVL ,%eax*/ + addlong((fetchdat >> 8) & 0xffff); + addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[0][cpu_rm]); + addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][cpu_rm]); + (*op_pc) += 2; + break; + } + addbyte(0x25); /*ANDL $0xffff, %eax*/ + addlong(0xffff); + addbyte(0xa3); + addlong((uint32_t) &cpu_state.eaaddr); - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL ,%eax*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - } - break; - case 1: - new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff); - addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc) += 4; - break; - } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); - break; - case 1: - addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - break; - case 2: - addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ - addbyte(0xC1); addbyte(0xE3); addbyte(2); /*SHL $2,%ebx*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - break; - case 3: - addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ - addbyte(0xC1); addbyte(0xE3); addbyte(3); /*SHL $2,%ebx*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - break; - } - } - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - } - else - { - if (!cpu_mod && cpu_rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[cpu_rm].l)); - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (cpu_mod == 1) - { - addbyte(0x05); - addlong((uint32_t)(int8_t)(fetchdat >> 8)); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x05); - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - } - return op_ea_seg; + if (mod1seg[cpu_rm] == &ss && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } + return op_ea_seg; } -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) +static x86seg * +codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { - codeblock_t *block = &codeblock[block_current]; - uint32_t op_32 = use32; - uint32_t op_pc = new_pc; - const OpFn *op_table = x86_dynarec_opcodes; - RecompOpFn *recomp_op_table = recomp_opcodes; - int opcode_shift = 0; - int opcode_mask = 0x3ff; - int over = 0; - int pc_off = 0; - int test_modrm = 1; - int c; + uint32_t new_eaaddr; - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 0; - op_old_pc = old_pc; + if (cpu_rm == 4) { + uint8_t sib = fetchdat >> 8; + (*op_pc)++; - for (c = 0; c < NR_HOST_REGS; c++) - host_reg_mapping[c] = -1; - mmx_ebx_ecx_loaded = 0; - for (c = 0; c < NR_HOST_XMM_REGS; c++) - host_reg_xmm_mapping[c] = -1; - - codegen_timing_start(); - - while (!over) - { - switch (opcode) - { - case 0x0f: - op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; - - case 0x26: /*ES:*/ - op_ea_seg = &cpu_state.seg_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &cpu_state.seg_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &cpu_state.seg_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &cpu_state.seg_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &cpu_state.seg_gs; - op_ssegs = 1; - break; - - case 0x66: /*Data size select*/ - op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); - break; - case 0x67: /*Address size select*/ - op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); - break; - - case 0xd8: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; - recomp_op_table = recomp_opcodes_d8; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xd9: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; - recomp_op_table = recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; - recomp_op_table = recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; - recomp_op_table = recomp_opcodes_dc; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdd: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; - recomp_op_table = recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; - recomp_op_table = recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; - recomp_op_table = recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - - case 0xf0: /*LOCK*/ - break; - - case 0xf2: /*REPNE*/ - op_table = x86_dynarec_opcodes_REPNE; - recomp_op_table = recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ - op_table = x86_dynarec_opcodes_REPE; - recomp_op_table = recomp_opcodes_REPE; - break; - - default: - goto generate_call; + switch (cpu_mod) { + case 0: + if ((sib & 7) == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL ,%eax*/ + addlong(new_eaaddr); + (*op_pc) += 4; + } else { + addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); } - fetchdat = fastreadl(cs + op_pc); - codegen_timing_prefix(opcode, fetchdat); - if (cpu_state.abrt) - return; - opcode = fetchdat & 0xff; - if (!pc_off) - fetchdat >>= 8; - - op_pc++; + break; + case 1: + new_eaaddr = (uint32_t) (int8_t) ((fetchdat >> 16) & 0xff); + addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ + addlong(new_eaaddr); + addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ + addlong(new_eaaddr); + addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + (*op_pc) += 4; + break; } + if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ + { + addbyte(0x05); + addlong(stack_offset); + } + if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (((sib >> 3) & 7) != 4) { + switch (sib >> 6) { + case 0: + addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); + break; + case 1: + addbyte(0x8B); + addbyte(0x5D); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ + addbyte(0x01); + addbyte(0xD8); /*ADDL %ebx,%eax*/ + addbyte(0x01); + addbyte(0xD8); /*ADDL %ebx,%eax*/ + break; + case 2: + addbyte(0x8B); + addbyte(0x5D); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ + addbyte(0xC1); + addbyte(0xE3); + addbyte(2); /*SHL $2,%ebx*/ + addbyte(0x01); + addbyte(0xD8); /*ADDL %ebx,%eax*/ + break; + case 3: + addbyte(0x8B); + addbyte(0x5D); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ + addbyte(0xC1); + addbyte(0xE3); + addbyte(3); /*SHL $2,%ebx*/ + addbyte(0x01); + addbyte(0xD8); /*ADDL %ebx,%eax*/ + break; + } + } + addbyte(0xa3); + addlong((uint32_t) &cpu_state.eaaddr); + } else { + if (!cpu_mod && cpu_rm == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + addlong(new_eaaddr); + (*op_pc) += 4; + return op_ea_seg; + } + addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[cpu_rm].l)); + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) { + if (cpu_rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (cpu_mod == 1) { + addbyte(0x05); + addlong((uint32_t) (int8_t) (fetchdat >> 8)); + (*op_pc)++; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x05); + addlong(new_eaaddr); + (*op_pc) += 4; + } + } + addbyte(0xa3); + addlong((uint32_t) &cpu_state.eaaddr); + } + return op_ea_seg; +} + +void +codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t op_32 = use32; + uint32_t op_pc = new_pc; + const OpFn *op_table = x86_dynarec_opcodes; + RecompOpFn *recomp_op_table = recomp_opcodes; + int opcode_shift = 0; + int opcode_mask = 0x3ff; + int over = 0; + int pc_off = 0; + int test_modrm = 1; + int c; + + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 0; + op_old_pc = old_pc; + + for (c = 0; c < NR_HOST_REGS; c++) + host_reg_mapping[c] = -1; + mmx_ebx_ecx_loaded = 0; + for (c = 0; c < NR_HOST_XMM_REGS; c++) + host_reg_xmm_mapping[c] = -1; + + codegen_timing_start(); + + while (!over) { + switch (opcode) { + case 0x0f: + op_table = x86_dynarec_opcodes_0f; + recomp_op_table = recomp_opcodes_0f; + over = 1; + break; + + case 0x26: /*ES:*/ + op_ea_seg = &cpu_state.seg_es; + op_ssegs = 1; + break; + case 0x2e: /*CS:*/ + op_ea_seg = &cpu_state.seg_cs; + op_ssegs = 1; + break; + case 0x36: /*SS:*/ + op_ea_seg = &cpu_state.seg_ss; + op_ssegs = 1; + break; + case 0x3e: /*DS:*/ + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 1; + break; + case 0x64: /*FS:*/ + op_ea_seg = &cpu_state.seg_fs; + op_ssegs = 1; + break; + case 0x65: /*GS:*/ + op_ea_seg = &cpu_state.seg_gs; + op_ssegs = 1; + break; + + case 0x66: /*Data size select*/ + op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); + break; + case 0x67: /*Address size select*/ + op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); + break; + + case 0xd8: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; + recomp_op_table = recomp_opcodes_d8; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xd9: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; + recomp_op_table = recomp_opcodes_d9; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xda: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; + recomp_op_table = recomp_opcodes_da; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdb: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; + recomp_op_table = recomp_opcodes_db; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdc: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; + recomp_op_table = recomp_opcodes_dc; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdd: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; + recomp_op_table = recomp_opcodes_dd; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xde: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; + recomp_op_table = recomp_opcodes_de; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdf: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; + recomp_op_table = recomp_opcodes_df; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + + case 0xf0: /*LOCK*/ + break; + + case 0xf2: /*REPNE*/ + op_table = x86_dynarec_opcodes_REPNE; + recomp_op_table = recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ + op_table = x86_dynarec_opcodes_REPE; + recomp_op_table = recomp_opcodes_REPE; + break; + + default: + goto generate_call; + } + fetchdat = fastreadl(cs + op_pc); + codegen_timing_prefix(opcode, fetchdat); + if (cpu_state.abrt) + return; + opcode = fetchdat & 0xff; + if (!pc_off) + fetchdat >>= 8; + + op_pc++; + } generate_call: - codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); + codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); - codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); - codegen_block_cycles = 0; + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + codegen_block_cycles = 0; - if ((op_table == x86_dynarec_opcodes && - ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || - (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || - (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || - (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) - { - /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with - subsequent instructions, so no cycles may have been deducted for it yet. - To prevent having zero cycle blocks (eg with a jump instruction pointing - to itself), apply the cycles that would be taken if this jump is taken, - then reverse it for subsequent instructions if the jump is not taken*/ - int jump_cycles = 0; + if ((op_table == x86_dynarec_opcodes && ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) { + /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with + subsequent instructions, so no cycles may have been deducted for it yet. + To prevent having zero cycle blocks (eg with a jump instruction pointing + to itself), apply the cycles that would be taken if this jump is taken, + then reverse it for subsequent instructions if the jump is not taken*/ + int jump_cycles = 0; if (codegen_timing_jump_cycles != NULL) jump_cycles = codegen_timing_jump_cycles(); - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, -jump_cycles); - codegen_accumulate_flush(); - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, jump_cycles); - } + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, -jump_cycles); + codegen_accumulate_flush(); + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, jump_cycles); + } - if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) - { - op_table = x86_dynarec_opcodes; - recomp_op_table = recomp_opcodes; - } + if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { + op_table = x86_dynarec_opcodes; + recomp_op_table = recomp_opcodes; + } - if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) - { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); - if (new_pc) - { - if (new_pc != -1) - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, new_pc); + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) { + uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); + if (new_pc) { + if (new_pc != -1) + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, new_pc); - codegen_block_ins++; - block->ins++; - codegen_block_full_ins++; - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_block_ins++; + block->ins++; + codegen_block_full_ins++; + codegen_endpc = (cs + cpu_state.pc) + 8; -#ifdef CHECK_INT +# ifdef CHECK_INT /* Check for interrupts. */ - addbyte(0xf6); /* test byte ptr[&pic_pending],1 */ + addbyte(0xf6); /* test byte ptr[&pic_pending],1 */ addbyte(0x05); addlong((uint32_t) (uintptr_t) &pic_pending); addbyte(0x01); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); -#endif + addbyte(0x0F); + addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t) &block->data[BLOCK_EXIT_OFFSET] - (uint32_t) (&block->data[block_pos + 4])); +# endif - return; - } + return; } + } - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - if (op_ssegs != last_ssegs) - { - last_ssegs = op_ssegs; + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + if (op_ssegs != last_ssegs) { + last_ssegs = op_ssegs; - addbyte(0xC6); /*MOVB [ssegs],op_ssegs*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ssegs)); - addbyte(op_pc + pc_off); - } - - if (!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) - { - int stack_offset = 0; - - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; - - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; - - addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(rm_data.rm_mod_reg_data)); - addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - - op_pc += pc_off; - if (cpu_mod != 3 && !(op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); - if (cpu_mod != 3 && (op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - op_pc -= pc_off; - } - - if (op_ea_seg != last_ea_seg) - { - last_ea_seg = op_ea_seg; - addbyte(0xC7); /*MOVL $&cpu_state.seg_ds,(ea_seg)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ea_seg)); - addlong((uint32_t)op_ea_seg); - } - - codegen_accumulate_flush(); - - addbyte(0xC7); /*MOVL pc,new_pc*/ + addbyte(0xC6); /*MOVB [ssegs],op_ssegs*/ addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); + addbyte((uint8_t) cpu_state_offset(ssegs)); + addbyte(op_pc + pc_off); + } + + if (!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) { + int stack_offset = 0; + + if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ + stack_offset = (op_32 & 0x100) ? 4 : 2; + + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; + + addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(rm_data.rm_mod_reg_data)); + addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); + + op_pc += pc_off; + if (cpu_mod != 3 && !(op_32 & 0x200)) + op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); + if (cpu_mod != 3 && (op_32 & 0x200)) + op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); + op_pc -= pc_off; + } + + if (op_ea_seg != last_ea_seg) { + last_ea_seg = op_ea_seg; + addbyte(0xC7); /*MOVL $&cpu_state.seg_ds,(ea_seg)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ea_seg)); + addlong((uint32_t) op_ea_seg); + } + + codegen_accumulate_flush(); + + addbyte(0xC7); /*MOVL pc,new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); addlong(op_pc + pc_off); - addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ + addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(old_pc); + + if (op_32 != last_op32) { + last_op32 = op_32; + addbyte(0xC7); /*MOVL $use32,(op32)*/ addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(old_pc); + addbyte((uint8_t) cpu_state_offset(op32)); + addlong(op_32); + } - if (op_32 != last_op32) - { - last_op32 = op_32; - addbyte(0xC7); /*MOVL $use32,(op32)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(op32)); - addlong(op_32); - } + addbyte(0xC7); /*MOVL $fetchdat,(%esp)*/ + addbyte(0x04); + addbyte(0x24); + addlong(fetchdat); - addbyte(0xC7); /*MOVL $fetchdat,(%esp)*/ - addbyte(0x04); - addbyte(0x24); - addlong(fetchdat); + addbyte(0xE8); /*CALL*/ + addlong(((uint8_t *) op - (uint8_t *) (&block->data[block_pos + 4]))); - addbyte(0xE8); /*CALL*/ - addlong(((uint8_t *)op - (uint8_t *)(&block->data[block_pos + 4]))); + codegen_block_ins++; - codegen_block_ins++; + block->ins++; - block->ins++; - -#ifdef CHECK_INT +# ifdef CHECK_INT /* Check for interrupts. */ - addbyte(0x0a); /* or al,byte ptr[&pic_pending] */ + addbyte(0x0a); /* or al,byte ptr[&pic_pending] */ addbyte(0x05); addlong((uint32_t) (uintptr_t) &pic_pending); -#endif +# endif - addbyte(0x09); /*OR %eax, %eax*/ - addbyte(0xc0); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); + addbyte(0x09); /*OR %eax, %eax*/ + addbyte(0xc0); + addbyte(0x0F); + addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t) &block->data[BLOCK_EXIT_OFFSET] - (uint32_t) (&block->data[block_pos + 4])); - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_endpc = (cs + cpu_state.pc) + 8; } #endif diff --git a/src/codegen/codegen_x86.h b/src/codegen/codegen_x86.h index 369614329..d6842eec1 100644 --- a/src/codegen/codegen_x86.h +++ b/src/codegen/codegen_x86.h @@ -1,24 +1,23 @@ -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff -#define BLOCK_START 0 +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff +#define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) #define BLOCK_EXIT_OFFSET 0x7f0 #ifdef OLD_GPF -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) +# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) #else -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14) +# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14) #endif #define BLOCK_MAX 1720 -enum -{ - OP_RET = 0xc3 +enum { + OP_RET = 0xc3 }; #define NR_HOST_REGS 4 diff --git a/src/codegen_new/CMakeLists.txt b/src/codegen_new/CMakeLists.txt index a96d0b57e..8c02060e4 100644 --- a/src/codegen_new/CMakeLists.txt +++ b/src/codegen_new/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # if(DYNAREC) diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index ef928dd51..2f178bc74 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -20,759 +20,710 @@ static struct { - uint32_t pc; - int op_ssegs; - x86seg *op_ea_seg; - uint32_t op_32; - int first_uop; - int TOP; + uint32_t pc; + int op_ssegs; + x86seg *op_ea_seg; + uint32_t op_32; + int first_uop; + int TOP; } codegen_instructions[MAX_INSTRUCTION_COUNT]; -int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP) +int +codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP) { - int c; + int c; - for (c = 0; c <= block->ins; c++) - { - if (codegen_instructions[c].pc == pc) - { - *first_instruction = c; - *TOP = codegen_instructions[c].TOP; - return codegen_instructions[c].first_uop; - } + for (c = 0; c <= block->ins; c++) { + if (codegen_instructions[c].pc == pc) { + *first_instruction = c; + *TOP = codegen_instructions[c].TOP; + return codegen_instructions[c].first_uop; } + } - *first_instruction = block->ins; - return -1; + *first_instruction = block->ins; + return -1; } -void codegen_set_loop_start(ir_data_t *ir, int first_instruction) +void +codegen_set_loop_start(ir_data_t *ir, int first_instruction) { - uop_MOV_IMM(ir, IREG_op32, codegen_instructions[first_instruction].op_32); - uop_MOV_PTR(ir, IREG_ea_seg, (void *)codegen_instructions[first_instruction].op_ea_seg); - uop_MOV_IMM(ir, IREG_ssegs, codegen_instructions[first_instruction].op_ssegs); + uop_MOV_IMM(ir, IREG_op32, codegen_instructions[first_instruction].op_32); + uop_MOV_PTR(ir, IREG_ea_seg, (void *) codegen_instructions[first_instruction].op_ea_seg); + uop_MOV_IMM(ir, IREG_ssegs, codegen_instructions[first_instruction].op_ssegs); } int has_ea; codeblock_t *codeblock; -uint16_t *codeblock_hash; +uint16_t *codeblock_hash; -void (*codegen_timing_start)(); +void (*codegen_timing_start)(void); void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); -void (*codegen_timing_block_start)(); -void (*codegen_timing_block_end)(); -int (*codegen_timing_jump_cycles)(); +void (*codegen_timing_block_start)(void); +void (*codegen_timing_block_end)(void); +int (*codegen_timing_jump_cycles)(void); -void codegen_timing_set(codegen_timing_t *timing) +void +codegen_timing_set(codegen_timing_t *timing) { - codegen_timing_start = timing->start; - codegen_timing_prefix = timing->prefix; - codegen_timing_opcode = timing->opcode; - codegen_timing_block_start = timing->block_start; - codegen_timing_block_end = timing->block_end; - codegen_timing_jump_cycles = timing->jump_cycles; + codegen_timing_start = timing->start; + codegen_timing_prefix = timing->prefix; + codegen_timing_opcode = timing->opcode; + codegen_timing_block_start = timing->block_start; + codegen_timing_block_end = timing->block_end; + codegen_timing_jump_cycles = timing->jump_cycles; } int codegen_in_recompile; -static int last_op_ssegs; -static x86seg *last_op_ea_seg; +static int last_op_ssegs; +static x86seg *last_op_ea_seg; static uint32_t last_op_32; -void codegen_generate_reset() +void +codegen_generate_reset(void) { - last_op_ssegs = -1; - last_op_ea_seg = NULL; - last_op_32 = -1; - has_ea = 0; + last_op_ssegs = -1; + last_op_ea_seg = NULL; + last_op_32 = -1; + has_ea = 0; } -void codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) +void +codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t) -1, codegen_gpf_rout); - seg->checked = 1; + seg->checked = 1; } -void codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) +void +codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t) -1, codegen_gpf_rout); - seg->checked = 1; + seg->checked = 1; } -static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +static x86seg * +codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { - uint32_t old_pc = (*op_pc) + 1; - if (!cpu_mod && cpu_rm == 6) - { - uint16_t addr = (fetchdat >> 8) & 0xffff; - uop_MOV_IMM(ir, IREG_eaaddr, addr); - (*op_pc) += 2; + uint32_t old_pc = (*op_pc) + 1; + if (!cpu_mod && cpu_rm == 6) { + uint16_t addr = (fetchdat >> 8) & 0xffff; + uop_MOV_IMM(ir, IREG_eaaddr, addr); + (*op_pc) += 2; + } else { + int base_reg, index_reg, offset; + + switch (cpu_rm & 7) { + case 0: + case 1: + case 7: + default: + base_reg = IREG_EBX; + break; + case 2: + case 3: + case 6: + base_reg = IREG_EBP; + break; + case 4: + base_reg = IREG_ESI; + break; + case 5: + base_reg = IREG_EDI; + break; } - else - { - int base_reg, index_reg, offset; + uop_MOV(ir, IREG_eaaddr, base_reg); - switch (cpu_rm & 7) - { - case 0: case 1: case 7: default: - base_reg = IREG_EBX; - break; - case 2: case 3: case 6: - base_reg = IREG_EBP; - break; - case 4: - base_reg = IREG_ESI; - break; - case 5: - base_reg = IREG_EDI; - break; - } - uop_MOV(ir, IREG_eaaddr, base_reg); + if (!(cpu_rm & 4)) { + if (!(cpu_rm & 1)) + index_reg = IREG_ESI; + else + index_reg = IREG_EDI; - if (!(cpu_rm & 4)) - { - if (!(cpu_rm & 1)) - index_reg = IREG_ESI; - else - index_reg = IREG_EDI; - - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, index_reg); - } - - switch (cpu_mod) - { - case 1: - offset = (int)(int8_t)((fetchdat >> 8) & 0xff); - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); - (*op_pc)++; - break; - case 2: - offset = (fetchdat >> 8) & 0xffff; - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); - (*op_pc) += 2; - break; - } - - uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); - - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - { - op_ea_seg = &cpu_state.seg_ss; - } + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, index_reg); } - codegen_mark_code_present(ir->block, cs+old_pc, ((*op_pc)+1)-old_pc); - return op_ea_seg; -} - -static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) -{ - codeblock_t *block = ir->block; - uint32_t old_pc = (*op_pc) + 1; - uint32_t new_eaaddr; - int extra_bytes = 0; - - if (cpu_rm == 4) - { - uint8_t sib = fetchdat >> 8; + switch (cpu_mod) { + case 1: + offset = (int) (int8_t) ((fetchdat >> 8) & 0xff); + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); (*op_pc)++; + break; + case 2: + offset = (fetchdat >> 8) & 0xffff; + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); + (*op_pc) += 2; + break; + } - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); - extra_bytes = 1; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - extra_bytes = 5; - } - (*op_pc) += 4; - } - else - { - uop_MOV(ir, IREG_eaaddr, sib & 7); - extra_bytes = 1; - } - break; - case 1: - new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff); + uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + + if (mod1seg[cpu_rm] == &ss && !op_ssegs) { + op_ea_seg = &cpu_state.seg_ss; + } + } + + codegen_mark_code_present(ir->block, cs + old_pc, ((*op_pc) + 1) - old_pc); + return op_ea_seg; +} + +static x86seg * +codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +{ + codeblock_t *block = ir->block; + uint32_t old_pc = (*op_pc) + 1; + uint32_t new_eaaddr; + int extra_bytes = 0; + + if (cpu_rm == 4) { + uint8_t sib = fetchdat >> 8; + (*op_pc)++; + + switch (cpu_mod) { + case 0: + if ((sib & 7) == 5) { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + extra_bytes = 1; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); - (*op_pc)++; - extra_bytes = 2; - break; - case 2: - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); - extra_bytes = 1; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - extra_bytes = 5; - } - (*op_pc) += 4; - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); - break; + extra_bytes = 5; + } + (*op_pc) += 4; + } else { + uop_MOV(ir, IREG_eaaddr, sib & 7); + extra_bytes = 1; } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, stack_offset); -// addbyte(0x05); -// addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7); - break; - case 1: - uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 1); - break; - case 2: - uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 2); - break; - case 3: - uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 3); - break; - } + break; + case 1: + new_eaaddr = (uint32_t) (int8_t) ((fetchdat >> 16) & 0xff); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); + (*op_pc)++; + extra_bytes = 2; + break; + case 2: + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + extra_bytes = 1; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 5; } + (*op_pc) += 4; + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); + break; } - else + if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ { - if (!cpu_mod && cpu_rm == 5) - { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - extra_bytes = 4; - } - - (*op_pc) += 4; - } - else - { - uop_MOV(ir, IREG_eaaddr, cpu_rm); - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (cpu_mod == 1) - { - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t)(int8_t)(fetchdat >> 8)); - (*op_pc)++; - extra_bytes = 1; - } - else - { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + (*op_pc) + 1); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_temp0); - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, new_eaaddr); - extra_bytes = 4; - } - (*op_pc) += 4; - } - } - } + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, stack_offset); + // addbyte(0x05); + // addlong(stack_offset); } + if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (((sib >> 3) & 7) != 4) { + switch (sib >> 6) { + case 0: + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7); + break; + case 1: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 1); + break; + case 2: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 2); + break; + case 3: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 3); + break; + } + } + } else { + if (!cpu_mod && cpu_rm == 5) { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 4; + } - if (extra_bytes) - codegen_mark_code_present(ir->block, cs+old_pc, extra_bytes); + (*op_pc) += 4; + } else { + uop_MOV(ir, IREG_eaaddr, cpu_rm); + if (cpu_mod) { + if (cpu_rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (cpu_mod == 1) { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t) (int8_t) (fetchdat >> 8)); + (*op_pc)++; + extra_bytes = 1; + } else { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + (*op_pc) + 1); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_temp0); + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, new_eaaddr); + extra_bytes = 4; + } + (*op_pc) += 4; + } + } + } + } - return op_ea_seg; + if (extra_bytes) + codegen_mark_code_present(ir->block, cs + old_pc, extra_bytes); + + return op_ea_seg; } -x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset) +x86seg * +codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset) { - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; - if ((fetchdat & 0xc0) == 0xc0) - return NULL; - if (op_32 & 0x200) - return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset); + if ((fetchdat & 0xc0) == 0xc0) + return NULL; + if (op_32 & 0x200) + return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset); - return codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc); + return codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc); } -static uint8_t opcode_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ +static uint8_t opcode_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ + 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ }; -static uint8_t opcode_0f_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ +static uint8_t opcode_0f_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ - 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ - 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ + 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ + 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ }; -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) +void +codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) { - codeblock_t *block = &codeblock[block_current]; - ir_data_t *ir = codegen_get_ir_data(); - uint32_t op_pc = new_pc; - OpFn *op_table = (OpFn *) x86_dynarec_opcodes; - RecompOpFn *recomp_op_table = recomp_opcodes; - int opcode_shift = 0; - int opcode_mask = 0x3ff; - uint32_t recomp_opcode_mask = 0x1ff; - uint32_t op_32 = use32; - int over = 0; - int test_modrm = 1; - int pc_off = 0; - uint32_t next_pc = 0; + codeblock_t *block = &codeblock[block_current]; + ir_data_t *ir = codegen_get_ir_data(); + uint32_t op_pc = new_pc; + OpFn *op_table = (OpFn *) x86_dynarec_opcodes; + RecompOpFn *recomp_op_table = recomp_opcodes; + int opcode_shift = 0; + int opcode_mask = 0x3ff; + uint32_t recomp_opcode_mask = 0x1ff; + uint32_t op_32 = use32; + int over = 0; + int test_modrm = 1; + int pc_off = 0; + uint32_t next_pc = 0; #ifdef DEBUG_EXTRA - uint8_t last_prefix = 0; + uint8_t last_prefix = 0; #endif - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 0; + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 0; - codegen_timing_start(); + codegen_timing_start(); - while (!over) - { - switch (opcode) - { - case 0x0f: + while (!over) { + switch (opcode) { + case 0x0f: #ifdef DEBUG_EXTRA - last_prefix = 0x0f; + last_prefix = 0x0f; #endif - op_table = (OpFn *) x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; + op_table = (OpFn *) x86_dynarec_opcodes_0f; + recomp_op_table = recomp_opcodes_0f; + over = 1; + break; - case 0x26: /*ES:*/ - op_ea_seg = &cpu_state.seg_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &cpu_state.seg_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &cpu_state.seg_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &cpu_state.seg_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &cpu_state.seg_gs; - op_ssegs = 1; - break; + case 0x26: /*ES:*/ + op_ea_seg = &cpu_state.seg_es; + op_ssegs = 1; + break; + case 0x2e: /*CS:*/ + op_ea_seg = &cpu_state.seg_cs; + op_ssegs = 1; + break; + case 0x36: /*SS:*/ + op_ea_seg = &cpu_state.seg_ss; + op_ssegs = 1; + break; + case 0x3e: /*DS:*/ + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 1; + break; + case 0x64: /*FS:*/ + op_ea_seg = &cpu_state.seg_fs; + op_ssegs = 1; + break; + case 0x65: /*GS:*/ + op_ea_seg = &cpu_state.seg_gs; + op_ssegs = 1; + break; - case 0x66: /*Data size select*/ - op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); - break; - case 0x67: /*Address size select*/ - op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); - break; + case 0x66: /*Data size select*/ + op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); + break; + case 0x67: /*Address size select*/ + op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); + break; - case 0xd8: + case 0xd8: #ifdef DEBUG_EXTRA - last_prefix = 0xd8; + last_prefix = 0xd8; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d8_a32 : (OpFn *) x86_dynarec_opcodes_d8_a16; - recomp_op_table = recomp_opcodes_d8; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xd9: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d8_a32 : (OpFn *) x86_dynarec_opcodes_d8_a16; + recomp_op_table = recomp_opcodes_d8; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xd9: #ifdef DEBUG_EXTRA - last_prefix = 0xd9; + last_prefix = 0xd9; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d9_a32 : (OpFn *) x86_dynarec_opcodes_d9_a16; - recomp_op_table = recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d9_a32 : (OpFn *) x86_dynarec_opcodes_d9_a16; + recomp_op_table = recomp_opcodes_d9; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xda: #ifdef DEBUG_EXTRA - last_prefix = 0xda; + last_prefix = 0xda; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_da_a32 : (OpFn *) x86_dynarec_opcodes_da_a16; - recomp_op_table = recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_da_a32 : (OpFn *) x86_dynarec_opcodes_da_a16; + recomp_op_table = recomp_opcodes_da; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdb: #ifdef DEBUG_EXTRA - last_prefix = 0xdb; + last_prefix = 0xdb; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_db_a32 : (OpFn *) x86_dynarec_opcodes_db_a16; - recomp_op_table = recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_db_a32 : (OpFn *) x86_dynarec_opcodes_db_a16; + recomp_op_table = recomp_opcodes_db; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdc: #ifdef DEBUG_EXTRA - last_prefix = 0xdc; + last_prefix = 0xdc; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dc_a32 : (OpFn *) x86_dynarec_opcodes_dc_a16; - recomp_op_table = recomp_opcodes_dc; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdd: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dc_a32 : (OpFn *) x86_dynarec_opcodes_dc_a16; + recomp_op_table = recomp_opcodes_dc; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdd: #ifdef DEBUG_EXTRA - last_prefix = 0xdd; + last_prefix = 0xdd; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dd_a32 : (OpFn *) x86_dynarec_opcodes_dd_a16; - recomp_op_table = recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dd_a32 : (OpFn *) x86_dynarec_opcodes_dd_a16; + recomp_op_table = recomp_opcodes_dd; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xde: #ifdef DEBUG_EXTRA - last_prefix = 0xde; + last_prefix = 0xde; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_de_a32 : (OpFn *) x86_dynarec_opcodes_de_a16; - recomp_op_table = recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_de_a32 : (OpFn *) x86_dynarec_opcodes_de_a16; + recomp_op_table = recomp_opcodes_de; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdf: #ifdef DEBUG_EXTRA - last_prefix = 0xdf; + last_prefix = 0xdf; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_df_a32 : (OpFn *) x86_dynarec_opcodes_df_a16; - recomp_op_table = recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_df_a32 : (OpFn *) x86_dynarec_opcodes_df_a16; + recomp_op_table = recomp_opcodes_df; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; - case 0xf0: /*LOCK*/ - break; + case 0xf0: /*LOCK*/ + break; - case 0xf2: /*REPNE*/ + case 0xf2: /*REPNE*/ #ifdef DEBUG_EXTRA - last_prefix = 0xf2; + last_prefix = 0xf2; #endif - op_table = (OpFn *) x86_dynarec_opcodes_REPNE; - recomp_op_table = NULL;//recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ + op_table = (OpFn *) x86_dynarec_opcodes_REPNE; + recomp_op_table = NULL; // recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ #ifdef DEBUG_EXTRA - last_prefix = 0xf3; + last_prefix = 0xf3; #endif - op_table = (OpFn *) x86_dynarec_opcodes_REPE; - recomp_op_table = NULL;//recomp_opcodes_REPE; - break; + op_table = (OpFn *) x86_dynarec_opcodes_REPE; + recomp_op_table = NULL; // recomp_opcodes_REPE; + break; - default: - goto generate_call; - } - fetchdat = fastreadl(cs + op_pc); - codegen_timing_prefix(opcode, fetchdat); - if (cpu_state.abrt) - return; - opcode = fetchdat & 0xff; - if (!pc_off) - fetchdat >>= 8; - - op_pc++; + default: + goto generate_call; } + fetchdat = fastreadl(cs + op_pc); + codegen_timing_prefix(opcode, fetchdat); + if (cpu_state.abrt) + return; + opcode = fetchdat & 0xff; + if (!pc_off) + fetchdat >>= 8; + + op_pc++; + } generate_call: - codegen_instructions[block->ins].pc = cpu_state.oldpc; - codegen_instructions[block->ins].op_ssegs = last_op_ssegs; - codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg; - codegen_instructions[block->ins].op_32 = last_op_32; - codegen_instructions[block->ins].TOP = cpu_state.TOP; - codegen_instructions[block->ins].first_uop = ir->wr_pos; + codegen_instructions[block->ins].pc = cpu_state.oldpc; + codegen_instructions[block->ins].op_ssegs = last_op_ssegs; + codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg; + codegen_instructions[block->ins].op_32 = last_op_32; + codegen_instructions[block->ins].TOP = cpu_state.TOP; + codegen_instructions[block->ins].first_uop = ir->wr_pos; - codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); + codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); - codegen_accumulate(ir, ACCREG_cycles, -codegen_block_cycles); - codegen_block_cycles = 0; + codegen_accumulate(ir, ACCREG_cycles, -codegen_block_cycles); + codegen_block_cycles = 0; - if ((op_table == x86_dynarec_opcodes && - ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || - (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || - (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || - (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) - { - /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with - subsequent instructions, so no cycles may have been deducted for it yet. - To prevent having zero cycle blocks (eg with a jump instruction pointing - to itself), apply the cycles that would be taken if this jump is taken, - then reverse it for subsequent instructions if the jump is not taken*/ - int jump_cycles = 0; + if ((op_table == x86_dynarec_opcodes && ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) { + /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with + subsequent instructions, so no cycles may have been deducted for it yet. + To prevent having zero cycle blocks (eg with a jump instruction pointing + to itself), apply the cycles that would be taken if this jump is taken, + then reverse it for subsequent instructions if the jump is not taken*/ + int jump_cycles = 0; - if (codegen_timing_jump_cycles) - codegen_timing_jump_cycles(); + if (codegen_timing_jump_cycles) + codegen_timing_jump_cycles(); - if (jump_cycles) - codegen_accumulate(ir, ACCREG_cycles, -jump_cycles); - codegen_accumulate_flush(ir); - if (jump_cycles) - codegen_accumulate(ir, ACCREG_cycles, jump_cycles); + if (jump_cycles) + codegen_accumulate(ir, ACCREG_cycles, -jump_cycles); + codegen_accumulate_flush(ir); + if (jump_cycles) + codegen_accumulate(ir, ACCREG_cycles, jump_cycles); + } + + if (op_table == x86_dynarec_opcodes_0f && opcode == 0x0f) { + /*3DNow opcodes are stored after ModR/M, SIB and any offset*/ + uint8_t modrm = fetchdat & 0xff; + uint8_t sib = (fetchdat >> 8) & 0xff; + uint32_t opcode_pc = op_pc + 1; + uint8_t opcode_3dnow; + + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 7) == 4) { + /* Has SIB*/ + opcode_pc++; + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((sib & 0x07) == 0x05) + opcode_pc += 4; + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((modrm & 0xc7) == 0x05) + opcode_pc += 4; + } + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } } - if (op_table == x86_dynarec_opcodes_0f && opcode == 0x0f) - { - /*3DNow opcodes are stored after ModR/M, SIB and any offset*/ - uint8_t modrm = fetchdat & 0xff; - uint8_t sib = (fetchdat >> 8) & 0xff; - uint32_t opcode_pc = op_pc + 1; - uint8_t opcode_3dnow; + opcode_3dnow = fastreadb(cs + opcode_pc); + if (recomp_opcodes_3DNOW[opcode_3dnow]) { + next_pc = opcode_pc + 1; - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 7) == 4) - { - /* Has SIB*/ - opcode_pc++; - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((sib & 0x07) == 0x05) - opcode_pc += 4; - } - else - { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((modrm & 0xc7) == 0x05) - opcode_pc += 4; - } - } - else - { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 2; - else if ((modrm & 0xc7) == 0x06) - opcode_pc += 2; - } - } - - opcode_3dnow = fastreadb(cs + opcode_pc); - if (recomp_opcodes_3DNOW[opcode_3dnow]) - { - next_pc = opcode_pc + 1; - - op_table = (OpFn *) x86_dynarec_opcodes_3DNOW; - recomp_op_table = recomp_opcodes_3DNOW; - opcode = opcode_3dnow; - recomp_opcode_mask = 0xff; - opcode_mask = 0xff; - } + op_table = (OpFn *) x86_dynarec_opcodes_3DNOW; + recomp_op_table = recomp_opcodes_3DNOW; + opcode = opcode_3dnow; + recomp_opcode_mask = 0xff; + opcode_mask = 0xff; } - codegen_mark_code_present(block, cs+old_pc, (op_pc - old_pc) - pc_off); - /* It is apparently a prefixed instruction. */ - // if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48)) - // goto codegen_skip; + } + codegen_mark_code_present(block, cs + old_pc, (op_pc - old_pc) - pc_off); + /* It is apparently a prefixed instruction. */ + // if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48)) + // goto codegen_skip; - if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) - { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc); - if (new_pc) - { - if (new_pc != -1) - uop_MOV_IMM(ir, IREG_pc, new_pc); + if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) { + uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc); + if (new_pc) { + if (new_pc != -1) + uop_MOV_IMM(ir, IREG_pc, new_pc); - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_endpc = (cs + cpu_state.pc) + 8; - block->ins++; + block->ins++; - if (block->ins >= MAX_INSTRUCTION_COUNT) - CPU_BLOCK_END(); + if (block->ins >= MAX_INSTRUCTION_COUNT) + CPU_BLOCK_END(); - return; - } + return; } + } -// codegen_skip: - if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) - { - op_table = (OpFn *) x86_dynarec_opcodes; - recomp_op_table = recomp_opcodes; + // codegen_skip: + if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { + op_table = (OpFn *) x86_dynarec_opcodes; + recomp_op_table = recomp_opcodes; + } + + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + + if (!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || (op_table == x86_dynarec_opcodes_3DNOW)) { + int stack_offset = 0; + + if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ + stack_offset = (op_32 & 0x100) ? 4 : 2; + + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; + + uop_MOV_IMM(ir, IREG_rm_mod_reg, cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); + + op_pc += pc_off; + if (cpu_mod != 3 && !(op_32 & 0x200)) { + op_ea_seg = codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); } - - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - - if (!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_3DNOW)) - { - int stack_offset = 0; - - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; - - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; - - uop_MOV_IMM(ir, IREG_rm_mod_reg, cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - - op_pc += pc_off; - if (cpu_mod != 3 && !(op_32 & 0x200)) - { - op_ea_seg = codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); - } - if (cpu_mod != 3 && (op_32 & 0x200)) - { - op_ea_seg = codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - } - op_pc -= pc_off; + if (cpu_mod != 3 && (op_32 & 0x200)) { + op_ea_seg = codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); } + op_pc -= pc_off; + } #ifdef DEBUG_EXTRA - uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); + uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); #endif - codegen_accumulate_flush(ir); - if (op_table == x86_dynarec_opcodes_3DNOW) - uop_MOV_IMM(ir, IREG_pc, next_pc); - else - uop_MOV_IMM(ir, IREG_pc, op_pc+pc_off); - uop_MOV_IMM(ir, IREG_oldpc, old_pc); - if (op_32 != last_op_32) - uop_MOV_IMM(ir, IREG_op32, op_32); - if (op_ea_seg != last_op_ea_seg) - uop_MOV_PTR(ir, IREG_ea_seg, (void *)op_ea_seg); - if (op_ssegs != last_op_ssegs) - uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); - uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); - uop_CALL_INSTRUCTION_FUNC(ir, op); - codegen_mark_code_present(block, cs+cpu_state.pc, 8); + codegen_accumulate_flush(ir); + if (op_table == x86_dynarec_opcodes_3DNOW) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, op_pc + pc_off); + uop_MOV_IMM(ir, IREG_oldpc, old_pc); + if (op_32 != last_op_32) + uop_MOV_IMM(ir, IREG_op32, op_32); + if (op_ea_seg != last_op_ea_seg) + uop_MOV_PTR(ir, IREG_ea_seg, (void *) op_ea_seg); + if (op_ssegs != last_op_ssegs) + uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); + uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); + uop_CALL_INSTRUCTION_FUNC(ir, op); + codegen_mark_code_present(block, cs + cpu_state.pc, 8); - last_op_32 = op_32; - last_op_ea_seg = op_ea_seg; - last_op_ssegs = op_ssegs; - //codegen_block_ins++; + last_op_32 = op_32; + last_op_ea_seg = op_ea_seg; + last_op_ssegs = op_ssegs; + // codegen_block_ins++; - block->ins++; + block->ins++; - if (block->ins >= MAX_INSTRUCTION_COUNT) - CPU_BLOCK_END(); + if (block->ins >= MAX_INSTRUCTION_COUNT) + CPU_BLOCK_END(); - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_endpc = (cs + cpu_state.pc) + 8; -// if (has_ea) -// fatal("Has EA\n"); + // if (has_ea) + // fatal("Has EA\n"); } diff --git a/src/codegen_new/codegen.h b/src/codegen_new/codegen.h index 082874f28..cc7e3f083 100644 --- a/src/codegen_new/codegen.h +++ b/src/codegen_new/codegen.h @@ -30,34 +30,33 @@ same page). */ -typedef struct codeblock_t -{ - uint32_t pc; - uint32_t _cs; - uint32_t phys, phys_2; - uint16_t status; - uint16_t flags; - uint8_t ins; - uint8_t TOP; +typedef struct codeblock_t { + uint32_t pc; + uint32_t _cs; + uint32_t phys, phys_2; + uint16_t status; + uint16_t flags; + uint8_t ins; + uint8_t TOP; - /*Pointers for codeblock tree, used to search for blocks when hash lookup - fails.*/ - uint16_t parent, left, right; + /*Pointers for codeblock tree, used to search for blocks when hash lookup + fails.*/ + uint16_t parent, left, right; - uint8_t *data; + uint8_t *data; - uint64_t page_mask, page_mask2; - uint64_t *dirty_mask, *dirty_mask2; + uint64_t page_mask, page_mask2; + uint64_t *dirty_mask, *dirty_mask2; - /*Previous and next pointers, for the codeblock list associated with - each physical page. Two sets of pointers, as a codeblock can be - present in two pages.*/ - uint16_t prev, next; - uint16_t prev_2, next_2; + /*Previous and next pointers, for the codeblock list associated with + each physical page. Two sets of pointers, as a codeblock can be + present in two pages.*/ + uint16_t prev, next; + uint16_t prev_2, next_2; - /*First mem_block_t used by this block. Any subsequent mem_block_ts - will be in the list starting at head_mem_block->next.*/ - struct mem_block_t *head_mem_block; + /*First mem_block_t used by this block. Any subsequent mem_block_ts + will be in the list starting at head_mem_block->next.*/ + struct mem_block_t *head_mem_block; } codeblock_t; extern codeblock_t *codeblock; @@ -83,262 +82,233 @@ extern uint8_t *block_write_data; /*Code block is not inlining immediate parameters, parameters must be fetched from memory*/ #define CODEBLOCK_NO_IMMEDIATES 0x80 -#define BLOCK_PC_INVALID 0xffffffff +#define BLOCK_PC_INVALID 0xffffffff -#define BLOCK_INVALID 0 +#define BLOCK_INVALID 0 -static inline int get_block_nr(codeblock_t *block) +static inline int +get_block_nr(codeblock_t *block) { - return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); + return ((uintptr_t) block - (uintptr_t) codeblock) / sizeof(codeblock_t); } -static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) +static inline codeblock_t * +codeblock_tree_find(uint32_t phys, uint32_t _cs) { - codeblock_t *block; - uint64_t a = _cs | ((uint64_t)phys << 32); + codeblock_t *block; + uint64_t a = _cs | ((uint64_t) phys << 32); - if (!pages[phys >> 12].head) - return NULL; + if (!pages[phys >> 12].head) + return NULL; - block = &codeblock[pages[phys >> 12].head]; - while (block) - { - uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32); - if (a == block_cmp) - { - if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) - break; - } - if (a < block_cmp) - block = block->left ? &codeblock[block->left] : NULL; - else - block = block->right ? &codeblock[block->right] : NULL; - } - - return block; -} - -static inline void codeblock_tree_add(codeblock_t *new_block) -{ - codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head]; - uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); - - if (!pages[new_block->phys >> 12].head) - { - pages[new_block->phys >> 12].head = get_block_nr(new_block); - new_block->parent = new_block->left = new_block->right = BLOCK_INVALID; + block = &codeblock[pages[phys >> 12].head]; + while (block) { + uint64_t block_cmp = block->_cs | ((uint64_t) block->phys << 32); + if (a == block_cmp) { + if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) + break; } + if (a < block_cmp) + block = block->left ? &codeblock[block->left] : NULL; else - { - codeblock_t *old_block = NULL; - uint64_t old_block_cmp = 0; + block = block->right ? &codeblock[block->right] : NULL; + } - while (block) - { - old_block = block; - old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32); - - if (a < old_block_cmp) - block = block->left ? &codeblock[block->left] : NULL; - else - block = block->right ? &codeblock[block->right] : NULL; - } - - if (a < old_block_cmp) - old_block->left = get_block_nr(new_block); - else - old_block->right = get_block_nr(new_block); - - new_block->parent = get_block_nr(old_block); - new_block->left = new_block->right = BLOCK_INVALID; - } + return block; } -static inline void codeblock_tree_delete(codeblock_t *block) +static inline void +codeblock_tree_add(codeblock_t *new_block) { - uint16_t parent_nr = block->parent; - codeblock_t *parent; + codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head]; + uint64_t a = new_block->_cs | ((uint64_t) new_block->phys << 32); - if (block->parent) - parent = &codeblock[block->parent]; + if (!pages[new_block->phys >> 12].head) { + pages[new_block->phys >> 12].head = get_block_nr(new_block); + new_block->parent = new_block->left = new_block->right = BLOCK_INVALID; + } else { + codeblock_t *old_block = NULL; + uint64_t old_block_cmp = 0; + + while (block) { + old_block = block; + old_block_cmp = old_block->_cs | ((uint64_t) old_block->phys << 32); + + if (a < old_block_cmp) + block = block->left ? &codeblock[block->left] : NULL; + else + block = block->right ? &codeblock[block->right] : NULL; + } + + if (a < old_block_cmp) + old_block->left = get_block_nr(new_block); else - parent = NULL; + old_block->right = get_block_nr(new_block); - if (!block->left && !block->right) - { - /*Easy case - remove from parent*/ - if (!parent) - pages[block->phys >> 12].head = BLOCK_INVALID; - else - { - uint16_t block_nr = get_block_nr(block); - - if (parent->left == block_nr) - parent->left = BLOCK_INVALID; - if (parent->right == block_nr) - parent->right = BLOCK_INVALID; - } - return; - } - else if (!block->left) - { - /*Only right node*/ - if (!parent_nr) - { - pages[block->phys >> 12].head = block->right; - codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; - } - else - { - uint16_t block_nr = get_block_nr(block); - - if (parent->left == block_nr) - { - parent->left = block->right; - codeblock[parent->left].parent = parent_nr; - } - if (parent->right == block_nr) - { - parent->right = block->right; - codeblock[parent->right].parent = parent_nr; - } - } - return; - } - else if (!block->right) - { - /*Only left node*/ - if (!parent_nr) - { - pages[block->phys >> 12].head = block->left; - codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; - } - else - { - uint16_t block_nr = get_block_nr(block); - - if (parent->left == block_nr) - { - parent->left = block->left; - codeblock[parent->left].parent = parent_nr; - } - if (parent->right == block_nr) - { - parent->right = block->left; - codeblock[parent->right].parent = parent_nr; - } - } - return; - } - else - { - /*Difficult case - node has two children. Walk right child to find lowest node*/ - codeblock_t *lowest = &codeblock[block->right], *highest; - codeblock_t *old_parent; - uint16_t lowest_nr; - - while (lowest->left) - lowest = &codeblock[lowest->left]; - lowest_nr = get_block_nr(lowest); - - old_parent = &codeblock[lowest->parent]; - - /*Replace deleted node with lowest node*/ - if (!parent_nr) - pages[block->phys >> 12].head = lowest_nr; - else - { - uint16_t block_nr = get_block_nr(block); - - if (parent->left == block_nr) - parent->left = lowest_nr; - if (parent->right == block_nr) - parent->right = lowest_nr; - } - - lowest->parent = parent_nr; - lowest->left = block->left; - if (lowest->left) - codeblock[lowest->left].parent = lowest_nr; - - old_parent->left = BLOCK_INVALID; - - highest = &codeblock[lowest->right]; - if (!lowest->right) - { - if (lowest_nr != block->right) - { - lowest->right = block->right; - codeblock[block->right].parent = lowest_nr; - } - return; - } - - while (highest->right) - highest = &codeblock[highest->right]; - - if (block->right && block->right != lowest_nr) - { - highest->right = block->right; - codeblock[block->right].parent = get_block_nr(highest); - } - } + new_block->parent = get_block_nr(old_block); + new_block->left = new_block->right = BLOCK_INVALID; + } } -#define PAGE_MASK_MASK 63 +static inline void +codeblock_tree_delete(codeblock_t *block) +{ + uint16_t parent_nr = block->parent; + codeblock_t *parent; + + if (block->parent) + parent = &codeblock[block->parent]; + else + parent = NULL; + + if (!block->left && !block->right) { + /*Easy case - remove from parent*/ + if (!parent) + pages[block->phys >> 12].head = BLOCK_INVALID; + else { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = BLOCK_INVALID; + if (parent->right == block_nr) + parent->right = BLOCK_INVALID; + } + return; + } else if (!block->left) { + /*Only right node*/ + if (!parent_nr) { + pages[block->phys >> 12].head = block->right; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; + } else { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) { + parent->left = block->right; + codeblock[parent->left].parent = parent_nr; + } + if (parent->right == block_nr) { + parent->right = block->right; + codeblock[parent->right].parent = parent_nr; + } + } + return; + } else if (!block->right) { + /*Only left node*/ + if (!parent_nr) { + pages[block->phys >> 12].head = block->left; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; + } else { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) { + parent->left = block->left; + codeblock[parent->left].parent = parent_nr; + } + if (parent->right == block_nr) { + parent->right = block->left; + codeblock[parent->right].parent = parent_nr; + } + } + return; + } else { + /*Difficult case - node has two children. Walk right child to find lowest node*/ + codeblock_t *lowest = &codeblock[block->right], *highest; + codeblock_t *old_parent; + uint16_t lowest_nr; + + while (lowest->left) + lowest = &codeblock[lowest->left]; + lowest_nr = get_block_nr(lowest); + + old_parent = &codeblock[lowest->parent]; + + /*Replace deleted node with lowest node*/ + if (!parent_nr) + pages[block->phys >> 12].head = lowest_nr; + else { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = lowest_nr; + if (parent->right == block_nr) + parent->right = lowest_nr; + } + + lowest->parent = parent_nr; + lowest->left = block->left; + if (lowest->left) + codeblock[lowest->left].parent = lowest_nr; + + old_parent->left = BLOCK_INVALID; + + highest = &codeblock[lowest->right]; + if (!lowest->right) { + if (lowest_nr != block->right) { + lowest->right = block->right; + codeblock[block->right].parent = lowest_nr; + } + return; + } + + while (highest->right) + highest = &codeblock[highest->right]; + + if (block->right && block->right != lowest_nr) { + highest->right = block->right; + codeblock[block->right].parent = get_block_nr(highest); + } + } +} + +#define PAGE_MASK_MASK 63 #define PAGE_MASK_SHIFT 6 void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len); -static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) +static inline void +codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) { - if (len == 1) - { - if (block->flags & CODEBLOCK_BYTE_MASK) - { - if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/ - block->page_mask |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); - else - block->page_mask2 |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); - } - else - { - if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/ - block->page_mask |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); - else - block->page_mask2 |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); - } + if (len == 1) { + if (block->flags & CODEBLOCK_BYTE_MASK) { + if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/ + block->page_mask |= ((uint64_t) 1 << (start_pc & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t) 1 << (start_pc & PAGE_MASK_MASK)); + } else { + if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/ + block->page_mask |= ((uint64_t) 1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t) 1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); } - else - codegen_mark_code_present_multibyte(block, start_pc, len); + } else + codegen_mark_code_present_multibyte(block, start_pc, len); } -void codegen_init(); -void codegen_close(); -void codegen_reset(); -void codegen_block_init(uint32_t phys_addr); -void codegen_block_remove(); -void codegen_block_start_recompile(codeblock_t *block); -void codegen_block_end_recompile(codeblock_t *block); -void codegen_block_end(); -void codegen_delete_block(codeblock_t *block); -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); -void codegen_generate_seg_restore(); -void codegen_set_op32(); -void codegen_flush(); -void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); +extern void codegen_init(void); +extern void codegen_close(void); +extern void codegen_reset(void); +extern void codegen_block_init(uint32_t phys_addr); +extern void codegen_block_remove(void); +extern void codegen_block_start_recompile(codeblock_t *block); +extern void codegen_block_end_recompile(codeblock_t *block); +extern void codegen_block_end(void); +extern void codegen_delete_block(codeblock_t *block); +extern void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); +extern void codegen_generate_seg_restore(void); +extern void codegen_set_op32(void); +extern void codegen_flush(void); +extern void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); struct ir_data_t; -x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset); -void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); -void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); +x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset); +extern void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); +extern void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); -int codegen_purge_purgable_list(); +extern int codegen_purge_purgable_list(void); /*Delete a random code block to free memory. This is obviously quite expensive, and will only be called when the allocator is out of memory*/ -void codegen_delete_random_block(int required_mem_block); +extern void codegen_delete_random_block(int required_mem_block); -extern int cpu_block_end; +extern int cpu_block_end; extern uint32_t codegen_endpc; extern int cpu_reps; @@ -346,21 +316,20 @@ extern int cpu_notreps; extern int codegen_block_cycles; -extern void (*codegen_timing_start)(); +extern void (*codegen_timing_start)(void); extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); -extern void (*codegen_timing_block_start)(); -extern void (*codegen_timing_block_end)(); -extern int (*codegen_timing_jump_cycles)(); +extern void (*codegen_timing_block_start)(void); +extern void (*codegen_timing_block_end)(void); +extern int (*codegen_timing_jump_cycles)(void); -typedef struct codegen_timing_t -{ - void (*start)(); - void (*prefix)(uint8_t prefix, uint32_t fetchdat); - void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); - void (*block_start)(); - void (*block_end)(); - int (*jump_cycles)(); +typedef struct codegen_timing_t { + void (*start)(void); + void (*prefix)(uint8_t prefix, uint32_t fetchdat); + void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); + void (*block_start)(void); + void (*block_end)(void); + int (*jump_cycles)(void); } codegen_timing_t; extern codegen_timing_t codegen_timing_pentium; @@ -371,7 +340,6 @@ extern codegen_timing_t codegen_timing_winchip2; extern codegen_timing_t codegen_timing_k6; extern codegen_timing_t codegen_timing_p6; - void codegen_timing_set(codegen_timing_t *timing); extern int block_current; @@ -382,8 +350,8 @@ extern int block_pos; /*Current physical page of block being recompiled. -1 if no recompilation taking place */ extern uint32_t recomp_page; -extern x86seg *op_ea_seg; -extern int op_ssegs; +extern x86seg *op_ea_seg; +extern int op_ssegs; extern uint32_t op_old_pc; /*Set to 1 if flags have been changed in the block being recompiled, and hence @@ -398,13 +366,13 @@ extern int codegen_reg_loaded[8]; extern int codegen_in_recompile; -void codegen_generate_reset(); +void codegen_generate_reset(void); -int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP); +int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP); void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction); #ifdef DEBUG_EXTRA -extern uint32_t instr_counts[256*256]; +extern uint32_t instr_counts[256 * 256]; #endif #endif diff --git a/src/codegen_new/codegen_accumulate.c b/src/codegen_new/codegen_accumulate.c index f15776b74..d9ae38af8 100644 --- a/src/codegen_new/codegen_accumulate.c +++ b/src/codegen_new/codegen_accumulate.c @@ -9,34 +9,36 @@ static struct { - int count; - int dest_reg; -} acc_regs[] = -{ - [ACCREG_cycles] = {0, IREG_cycles} + int count; + int dest_reg; +} acc_regs[] = { + [ACCREG_cycles] = {0, IREG_cycles} }; -void codegen_accumulate(ir_data_t *ir, int acc_reg, int delta) +void +codegen_accumulate(ir_data_t *ir, int acc_reg, int delta) { - acc_regs[acc_reg].count += delta; + acc_regs[acc_reg].count += delta; #ifdef USE_ACYCS - if ((acc_reg == ACCREG_cycles) && (delta != 0)) { - uop_ADD_IMM(ir, IREG_acycs, IREG_acycs, -delta); - } + if ((acc_reg == ACCREG_cycles) && (delta != 0)) { + uop_ADD_IMM(ir, IREG_acycs, IREG_acycs, -delta); + } #endif } -void codegen_accumulate_flush(ir_data_t *ir) +void +codegen_accumulate_flush(ir_data_t *ir) { - if (acc_regs[0].count) { - uop_ADD_IMM(ir, acc_regs[0].dest_reg, acc_regs[0].dest_reg, acc_regs[0].count); - } + if (acc_regs[0].count) { + uop_ADD_IMM(ir, acc_regs[0].dest_reg, acc_regs[0].dest_reg, acc_regs[0].count); + } - acc_regs[0].count = 0; + acc_regs[0].count = 0; } -void codegen_accumulate_reset() +void +codegen_accumulate_reset(void) { - acc_regs[0].count = 0; + acc_regs[0].count = 0; } diff --git a/src/codegen_new/codegen_accumulate.h b/src/codegen_new/codegen_accumulate.h index 908dba2e2..5744c6362 100644 --- a/src/codegen_new/codegen_accumulate.h +++ b/src/codegen_new/codegen_accumulate.h @@ -1,12 +1,11 @@ -enum -{ - ACCREG_cycles = 0, +enum { + ACCREG_cycles = 0, - ACCREG_COUNT + ACCREG_COUNT }; struct ir_data_t; void codegen_accumulate(struct ir_data_t *ir, int acc_reg, int delta); void codegen_accumulate_flush(struct ir_data_t *ir); -void codegen_accumulate_reset(); +void codegen_accumulate_reset(void); diff --git a/src/codegen_new/codegen_allocator.c b/src/codegen_new/codegen_allocator.c index baeea52b6..2badc35e8 100644 --- a/src/codegen_new/codegen_allocator.c +++ b/src/codegen_new/codegen_allocator.c @@ -1,10 +1,10 @@ #if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) -#include -#include -#include +# include +# include +# include #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 -#include +# include #endif #include @@ -17,118 +17,116 @@ #include "codegen.h" #include "codegen_allocator.h" -typedef struct mem_block_t -{ - uint32_t offset; /*Offset into mem_block_alloc*/ - uint32_t next; - uint16_t code_block; +typedef struct mem_block_t { + uint32_t offset; /*Offset into mem_block_alloc*/ + uint32_t next; + uint16_t code_block; } mem_block_t; static mem_block_t mem_blocks[MEM_BLOCK_NR]; -static uint32_t mem_block_free_list; -static uint8_t *mem_block_alloc = NULL; +static uint32_t mem_block_free_list; +static uint8_t *mem_block_alloc = NULL; int codegen_allocator_usage = 0; -void codegen_allocator_init() +void +codegen_allocator_init(void) { - int c; + int c; #if defined WIN32 || defined _WIN32 || defined _WIN32 - mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - /* TODO: check deployment target: older Intel-based versions of macOS don't play - nice with MAP_JIT. */ + mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + /* TODO: check deployment target: older Intel-based versions of macOS don't play + nice with MAP_JIT. */ #elif defined(__APPLE__) && defined(MAP_JIT) - mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE|MAP_JIT, -1, 0); + mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE | MAP_JIT, -1, 0); #else - mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); + mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); #endif - for (c = 0; c < MEM_BLOCK_NR; c++) - { - mem_blocks[c].offset = c * MEM_BLOCK_SIZE; - mem_blocks[c].code_block = BLOCK_INVALID; - if (c < MEM_BLOCK_NR-1) - mem_blocks[c].next = c+2; - else - mem_blocks[c].next = 0; - } - mem_block_free_list = 1; -} - -mem_block_t *codegen_allocator_allocate(mem_block_t *parent, int code_block) -{ - mem_block_t *block; - uint32_t block_nr; - - while (!mem_block_free_list) - { - /*Pick a random memory block and free the owning code block*/ - block_nr = rand() & MEM_BLOCK_MASK; - block = &mem_blocks[block_nr]; - - if (block->code_block && block->code_block != code_block) - codegen_delete_block(&codeblock[block->code_block]); - } - - /*Remove from free list*/ - block_nr = mem_block_free_list; - block = &mem_blocks[block_nr-1]; - mem_block_free_list = block->next; - - block->code_block = code_block; - if (parent) - { - /*Add to parent list*/ - block->next = parent->next; - parent->next = block_nr; - } + for (c = 0; c < MEM_BLOCK_NR; c++) { + mem_blocks[c].offset = c * MEM_BLOCK_SIZE; + mem_blocks[c].code_block = BLOCK_INVALID; + if (c < MEM_BLOCK_NR - 1) + mem_blocks[c].next = c + 2; else - block->next = 0; - - codegen_allocator_usage++; - return block; + mem_blocks[c].next = 0; + } + mem_block_free_list = 1; } -void codegen_allocator_free(mem_block_t *block) + +mem_block_t * +codegen_allocator_allocate(mem_block_t *parent, int code_block) { - int block_nr = (((uintptr_t)block - (uintptr_t)mem_blocks) / sizeof(mem_block_t)) + 1; + mem_block_t *block; + uint32_t block_nr; - while (1) - { - int next_block_nr = block->next; - codegen_allocator_usage--; + while (!mem_block_free_list) { + /*Pick a random memory block and free the owning code block*/ + block_nr = rand() & MEM_BLOCK_MASK; + block = &mem_blocks[block_nr]; - block->next = mem_block_free_list; - block->code_block = BLOCK_INVALID; - mem_block_free_list = block_nr; - block_nr = next_block_nr; + if (block->code_block && block->code_block != code_block) + codegen_delete_block(&codeblock[block->code_block]); + } - if (block_nr) - block = &mem_blocks[block_nr - 1]; - else - break; - } + /*Remove from free list*/ + block_nr = mem_block_free_list; + block = &mem_blocks[block_nr - 1]; + mem_block_free_list = block->next; + + block->code_block = code_block; + if (parent) { + /*Add to parent list*/ + block->next = parent->next; + parent->next = block_nr; + } else + block->next = 0; + + codegen_allocator_usage++; + return block; } - -uint8_t *codeblock_allocator_get_ptr(mem_block_t *block) +void +codegen_allocator_free(mem_block_t *block) { - return &mem_block_alloc[block->offset]; + int block_nr = (((uintptr_t) block - (uintptr_t) mem_blocks) / sizeof(mem_block_t)) + 1; + + while (1) { + int next_block_nr = block->next; + codegen_allocator_usage--; + + block->next = mem_block_free_list; + block->code_block = BLOCK_INVALID; + mem_block_free_list = block_nr; + block_nr = next_block_nr; + + if (block_nr) + block = &mem_blocks[block_nr - 1]; + else + break; + } } -void codegen_allocator_clean_blocks(struct mem_block_t *block) +uint8_t * +codeblock_allocator_get_ptr(mem_block_t *block) +{ + return &mem_block_alloc[block->offset]; +} + +void +codegen_allocator_clean_blocks(struct mem_block_t *block) { #if defined __ARM_EABI__ || defined _ARM_ || defined __aarch64__ || defined _M_ARM || defined _M_ARM64 - while (1) - { -#ifndef _MSC_VER - __clear_cache(&mem_block_alloc[block->offset], &mem_block_alloc[block->offset + MEM_BLOCK_SIZE]); -#else - FlushInstructionCache(GetCurrentProcess(), &mem_block_alloc[block->offset], MEM_BLOCK_SIZE); -#endif - if (block->next) - block = &mem_blocks[block->next - 1]; - else - break; - } + while (1) { +# ifndef _MSC_VER + __clear_cache(&mem_block_alloc[block->offset], &mem_block_alloc[block->offset + MEM_BLOCK_SIZE]); +# else + FlushInstructionCache(GetCurrentProcess(), &mem_block_alloc[block->offset], MEM_BLOCK_SIZE); +# endif + if (block->next) + block = &mem_blocks[block->next - 1]; + else + break; + } #endif } diff --git a/src/codegen_new/codegen_allocator.h b/src/codegen_new/codegen_allocator.h index f9e70d248..21d4dbb0c 100644 --- a/src/codegen_new/codegen_allocator.h +++ b/src/codegen_new/codegen_allocator.h @@ -14,15 +14,15 @@ instruction. ARMv7 is restricted to +/- 32 MB, ARMv8 to +/- 128 MB, x86 to +/- 2GB. As a result, total memory size is limited to 32 MB on ARMv7*/ #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#define MEM_BLOCK_NR 32768 +# define MEM_BLOCK_NR 32768 #else -#define MEM_BLOCK_NR 131072 +# define MEM_BLOCK_NR 131072 #endif -#define MEM_BLOCK_MASK (MEM_BLOCK_NR-1) +#define MEM_BLOCK_MASK (MEM_BLOCK_NR - 1) #define MEM_BLOCK_SIZE 0x3c0 -void codegen_allocator_init(); +void codegen_allocator_init(void); /*Allocate a mem_block_t, and the associated backing memory. If parent is non-NULL, then the new block will be added to the list in parent->next*/ diff --git a/src/codegen_new/codegen_backend.h b/src/codegen_new/codegen_backend.h index 56884c84b..901b5e9d9 100644 --- a/src/codegen_new/codegen_backend.h +++ b/src/codegen_new/codegen_backend.h @@ -2,25 +2,25 @@ #define _CODEGEN_BACKEND_H_ #if defined __amd64__ || defined _M_X64 -#include "codegen_backend_x86-64.h" +# include "codegen_backend_x86-64.h" #elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include "codegen_backend_x86.h" +# include "codegen_backend_x86.h" #elif defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#include "codegen_backend_arm.h" +# include "codegen_backend_arm.h" #elif defined __aarch64__ || defined _M_ARM64 -#include "codegen_backend_arm64.h" +# include "codegen_backend_arm64.h" #else -#error Dynamic recompiler not implemented on your platform +# error Dynamic recompiler not implemented on your platform #endif -void codegen_backend_init(); +void codegen_backend_init(void); void codegen_backend_prologue(codeblock_t *block); void codegen_backend_epilogue(codeblock_t *block); struct ir_data_t; struct uop_t; -struct ir_data_t *codegen_get_ir_data(); +struct ir_data_t *codegen_get_ir_data(void); typedef int (*uOpFn)(codeblock_t *codeblock, struct uop_t *uop); @@ -29,10 +29,9 @@ extern const uOpFn uop_handlers[]; /*Register will not be preserved across function calls*/ #define HOST_REG_FLAG_VOLATILE (1 << 0) -typedef struct host_reg_def_t -{ - int reg; - int flags; +typedef struct host_reg_def_t { + int reg; + int flags; } host_reg_def_t; extern host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS]; diff --git a/src/codegen_new/codegen_backend_arm.c b/src/codegen_new/codegen_backend_arm.c index 7030c401a..a389f239f 100644 --- a/src/codegen_new/codegen_backend_arm.c +++ b/src/codegen_new/codegen_backend_arm.c @@ -1,28 +1,28 @@ #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm_defs.h" -#include "codegen_backend_arm_ops.h" -#include "codegen_reg.h" -#include "x86.h" -#include "x87.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm_defs.h" +# include "codegen_backend_arm_ops.h" +# include "codegen_reg.h" +# include "x86.h" +# include "x87.h" -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#include -#endif -#include +# if defined(__linux__) || defined(__APPLE__) +# include +# include +# endif +# if defined WIN32 || defined _WIN32 || defined _WIN32 +# include +# endif +# include void *codegen_mem_load_byte; void *codegen_mem_load_word; @@ -43,329 +43,325 @@ void *codegen_fp_round; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - {REG_R4, 0}, - {REG_R5, 0}, - {REG_R6, 0}, - {REG_R7, 0}, - {REG_R8, 0}, - {REG_R9, 0}, - {REG_R11, 0} +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + {REG_R4, 0}, + { REG_R5, 0}, + { REG_R6, 0}, + { REG_R7, 0}, + { REG_R8, 0}, + { REG_R9, 0}, + { REG_R11, 0} }; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ - {REG_D8, 0}, - {REG_D9, 0}, - {REG_D10, 0}, - {REG_D11, 0}, - {REG_D12, 0}, - {REG_D13, 0}, - {REG_D14, 0}, - {REG_D15, 0} +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { + {REG_D8, 0}, + { REG_D9, 0}, + { REG_D10, 0}, + { REG_D11, 0}, + { REG_D12, 0}, + { REG_D13, 0}, + { REG_D14, 0}, + { REG_D15, 0} }; -static void build_load_routine(codeblock_t *block, int size, int is_float) +static void +build_load_routine(codeblock_t *block, int size, int is_float) { - uint32_t *branch_offset; - uint32_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - R0 = address - Out - R0 = data, R1 = abrt*/ - /*MOV R1, R0, LSR #12 - MOV R2, #readlookup2 - LDR R1, [R2, R1, LSL #2] - CMP R1, #-1 - BNE + - LDRB R0, [R1, R0] - MOV R1, #0 - MOV PC, LR - * STR LR, [SP, -4]! - BL readmembl - LDRB R1, cpu_state.abrt - LDR PC, [SP], #4 - */ - codegen_alloc(block, 80); - host_arm_MOV_REG_LSR(block, REG_R1, REG_R0, 12); - host_arm_MOV_IMM(block, REG_R2, (uint32_t)readlookup2); - host_arm_LDR_REG_LSL(block, REG_R1, REG_R2, REG_R1, 2); - if (size != 1) - { - host_arm_TST_IMM(block, REG_R0, size-1); - misaligned_offset = host_arm_BNE_(block); - } - host_arm_CMP_IMM(block, REG_R1, -1); - branch_offset = host_arm_BEQ_(block); - if (size == 1 && !is_float) - host_arm_LDRB_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 2 && !is_float) - host_arm_LDRH_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 4 && !is_float) - host_arm_LDR_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 4 && is_float) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); - host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0); - } - else if (size == 8) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); - host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0); - } - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_MOV_REG(block, REG_PC, REG_LR); + /*In - R0 = address + Out - R0 = data, R1 = abrt*/ + /*MOV R1, R0, LSR #12 + MOV R2, #readlookup2 + LDR R1, [R2, R1, LSL #2] + CMP R1, #-1 + BNE + + LDRB R0, [R1, R0] + MOV R1, #0 + MOV PC, LR + * STR LR, [SP, -4]! + BL readmembl + LDRB R1, cpu_state.abrt + LDR PC, [SP], #4 + */ + codegen_alloc(block, 80); + host_arm_MOV_REG_LSR(block, REG_R1, REG_R0, 12); + host_arm_MOV_IMM(block, REG_R2, (uint32_t) readlookup2); + host_arm_LDR_REG_LSL(block, REG_R1, REG_R2, REG_R1, 2); + if (size != 1) { + host_arm_TST_IMM(block, REG_R0, size - 1); + misaligned_offset = host_arm_BNE_(block); + } + host_arm_CMP_IMM(block, REG_R1, -1); + branch_offset = host_arm_BEQ_(block); + if (size == 1 && !is_float) + host_arm_LDRB_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 2 && !is_float) + host_arm_LDRH_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 4 && !is_float) + host_arm_LDR_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 4 && is_float) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); + host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0); + } else if (size == 8) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); + host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0); + } + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_MOV_REG(block, REG_PC, REG_LR); - *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; - if (size != 1) - *misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; - host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); - if (size == 1) - host_arm_BL(block, (uintptr_t)readmembl); - else if (size == 2) - host_arm_BL(block, (uintptr_t)readmemwl); - else if (size == 4) - host_arm_BL(block, (uintptr_t)readmemll); - else if (size == 8) - host_arm_BL(block, (uintptr_t)readmemql); - else - fatal("build_load_routine - unknown size %i\n", size); - if (size == 4 && is_float) - host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0); - else if (size == 8) - host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); - host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); - host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); + *branch_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 8) & 0x3fffffc) >> 2; + if (size != 1) + *misaligned_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 8) & 0x3fffffc) >> 2; + host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); + if (size == 1) + host_arm_BL(block, (uintptr_t) readmembl); + else if (size == 2) + host_arm_BL(block, (uintptr_t) readmemwl); + else if (size == 4) + host_arm_BL(block, (uintptr_t) readmemll); + else if (size == 8) + host_arm_BL(block, (uintptr_t) readmemql); + else + fatal("build_load_routine - unknown size %i\n", size); + if (size == 4 && is_float) + host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0); + else if (size == 8) + host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); + host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); + host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); } -static void build_store_routine(codeblock_t *block, int size, int is_float) +static void +build_store_routine(codeblock_t *block, int size, int is_float) { - uint32_t *branch_offset; - uint32_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - R0 = address - Out - R0 = data, R1 = abrt*/ - /*MOV R1, R0, LSR #12 - MOV R2, #readlookup2 - LDR R1, [R2, R1, LSL #2] - CMP R1, #-1 - BNE + - LDRB R0, [R1, R0] - MOV R1, #0 - MOV PC, LR - * STR LR, [SP, -4]! - BL readmembl - LDRB R1, cpu_state.abrt - LDR PC, [SP], #4 - */ - codegen_alloc(block, 80); - host_arm_MOV_REG_LSR(block, REG_R2, REG_R0, 12); - host_arm_MOV_IMM(block, REG_R3, (uint32_t)writelookup2); - host_arm_LDR_REG_LSL(block, REG_R2, REG_R3, REG_R2, 2); - if (size != 1) - { - host_arm_TST_IMM(block, REG_R0, size-1); - misaligned_offset = host_arm_BNE_(block); - } - host_arm_CMP_IMM(block, REG_R2, -1); - branch_offset = host_arm_BEQ_(block); - if (size == 1 && !is_float) - host_arm_STRB_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 2 && !is_float) - host_arm_STRH_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 4 && !is_float) - host_arm_STR_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 4 && is_float) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); - host_arm_VSTR_S(block, REG_D_TEMP, REG_R0, 0); - } - else if (size == 8) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); - host_arm_VSTR_D(block, REG_D_TEMP, REG_R0, 0); - } - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_MOV_REG(block, REG_PC, REG_LR); + /*In - R0 = address + Out - R0 = data, R1 = abrt*/ + /*MOV R1, R0, LSR #12 + MOV R2, #readlookup2 + LDR R1, [R2, R1, LSL #2] + CMP R1, #-1 + BNE + + LDRB R0, [R1, R0] + MOV R1, #0 + MOV PC, LR + * STR LR, [SP, -4]! + BL readmembl + LDRB R1, cpu_state.abrt + LDR PC, [SP], #4 + */ + codegen_alloc(block, 80); + host_arm_MOV_REG_LSR(block, REG_R2, REG_R0, 12); + host_arm_MOV_IMM(block, REG_R3, (uint32_t) writelookup2); + host_arm_LDR_REG_LSL(block, REG_R2, REG_R3, REG_R2, 2); + if (size != 1) { + host_arm_TST_IMM(block, REG_R0, size - 1); + misaligned_offset = host_arm_BNE_(block); + } + host_arm_CMP_IMM(block, REG_R2, -1); + branch_offset = host_arm_BEQ_(block); + if (size == 1 && !is_float) + host_arm_STRB_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 2 && !is_float) + host_arm_STRH_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 4 && !is_float) + host_arm_STR_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 4 && is_float) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); + host_arm_VSTR_S(block, REG_D_TEMP, REG_R0, 0); + } else if (size == 8) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); + host_arm_VSTR_D(block, REG_D_TEMP, REG_R0, 0); + } + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_MOV_REG(block, REG_PC, REG_LR); - *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; - if (size != 1) - *misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; - host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); - if (size == 4 && is_float) - host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP); - else if (size == 8) - host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP); - if (size == 1) - host_arm_BL(block, (uintptr_t)writemembl); - else if (size == 2) - host_arm_BL(block, (uintptr_t)writememwl); - else if (size == 4) - host_arm_BL(block, (uintptr_t)writememll); - else if (size == 8) - host_arm_BL_r1(block, (uintptr_t)writememql); - else - fatal("build_store_routine - unknown size %i\n", size); - host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); - host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); + *branch_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 8) & 0x3fffffc) >> 2; + if (size != 1) + *misaligned_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 8) & 0x3fffffc) >> 2; + host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); + if (size == 4 && is_float) + host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP); + else if (size == 8) + host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP); + if (size == 1) + host_arm_BL(block, (uintptr_t) writemembl); + else if (size == 2) + host_arm_BL(block, (uintptr_t) writememwl); + else if (size == 4) + host_arm_BL(block, (uintptr_t) writememll); + else if (size == 8) + host_arm_BL_r1(block, (uintptr_t) writememql); + else + fatal("build_store_routine - unknown size %i\n", size); + host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); + host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); } -static void build_loadstore_routines(codeblock_t *block) +static void +build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &block_write_data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &block_write_data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &block_write_data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &block_write_data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &block_write_data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &block_write_data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &block_write_data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &block_write_data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &block_write_data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &block_write_data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &block_write_data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &block_write_data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &block_write_data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &block_write_data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &block_write_data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &block_write_data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &block_write_data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &block_write_data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &block_write_data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &block_write_data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &block_write_data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &block_write_data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &block_write_data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &block_write_data[block_pos]; + build_store_routine(block, 8, 1); } /*VFP has a specific round-to-zero instruction, and the default rounding mode is nearest. For round up/down, temporarily change the rounding mode in FPCSR*/ -#define FPCSR_ROUNDING_MASK (3 << 22) -#define FPCSR_ROUNDING_UP (1 << 22) -#define FPCSR_ROUNDING_DOWN (2 << 22) +# define FPCSR_ROUNDING_MASK (3 << 22) +# define FPCSR_ROUNDING_UP (1 << 22) +# define FPCSR_ROUNDING_DOWN (2 << 22) -static void build_fp_round_routine(codeblock_t *block) +static void +build_fp_round_routine(codeblock_t *block) { - uint32_t *jump_table; + uint32_t *jump_table; - codegen_alloc(block, 80); + codegen_alloc(block, 80); - host_arm_MOV_REG(block, REG_TEMP2, REG_LR); - host_arm_MOV_REG(block, REG_LR, REG_TEMP2); - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); - host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP); - host_arm_NOP(block); + host_arm_MOV_REG(block, REG_TEMP2, REG_LR); + host_arm_MOV_REG(block, REG_LR, REG_TEMP2); + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.new_fp_control - (uintptr_t) &cpu_state); + host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP); + host_arm_NOP(block); - jump_table = (uint32_t *)&block_write_data[block_pos]; - host_arm_NOP(block); - host_arm_NOP(block); - host_arm_NOP(block); - host_arm_NOP(block); + jump_table = (uint32_t *) &block_write_data[block_pos]; + host_arm_NOP(block); + host_arm_NOP(block); + host_arm_NOP(block); + host_arm_NOP(block); - jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even - host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_NEAREST] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // tie even + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //pos inf - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); - host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); - host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP2, FPCSR_ROUNDING_UP); - host_arm_VMSR_FPSCR(block, REG_TEMP2); - host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_VMSR_FPSCR(block, REG_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_UP] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // pos inf + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.old_fp_control - (uintptr_t) &cpu_state); + host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); + host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP2, FPCSR_ROUNDING_UP); + host_arm_VMSR_FPSCR(block, REG_TEMP2); + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_VMSR_FPSCR(block, REG_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //neg inf - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); - host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); - host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_DOWN); - host_arm_VMSR_FPSCR(block, REG_TEMP2); - host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_VMSR_FPSCR(block, REG_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_DOWN] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // neg inf + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.old_fp_control - (uintptr_t) &cpu_state); + host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); + host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_DOWN); + host_arm_VMSR_FPSCR(block, REG_TEMP2); + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_VMSR_FPSCR(block, REG_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //zero - host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_CHOP] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // zero + host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); } -void codegen_backend_init() +void +codegen_backend_init(void) { - codeblock_t *block; - int c; + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block_write_data = block->data; - build_loadstore_routines(&codeblock[block_current]); -//pclog("block_pos=%i\n", block_pos); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(&codeblock[block_current]); + // pclog("block_pos=%i\n", block_pos); - codegen_fp_round = &block_write_data[block_pos]; - build_fp_round_routine(&codeblock[block_current]); + codegen_fp_round = &block_write_data[block_pos]; + build_fp_round_routine(&codeblock[block_current]); - codegen_alloc(block, 80); - codegen_gpf_rout = &block_write_data[block_pos]; - host_arm_MOV_IMM(block, REG_R0, 0); - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_call(block, x86gpf); + codegen_alloc(block, 80); + codegen_gpf_rout = &block_write_data[block_pos]; + host_arm_MOV_IMM(block, REG_R0, 0); + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_call(block, x86gpf); - codegen_exit_rout = &block_write_data[block_pos]; - host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); + codegen_exit_rout = &block_write_data[block_pos]; + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); - block_write_data = NULL; -//fatal("block_pos=%i\n", block_pos); - asm("vmrs %0, fpscr\n" - : "=r" (cpu_state.old_fp_control) - ); - if ((cpu_state.old_fp_control >> 22) & 3) - fatal("VFP not in nearest rounding mode\n"); + block_write_data = NULL; + // fatal("block_pos=%i\n", block_pos); + asm("vmrs %0, fpscr\n" + : "=r"(cpu_state.old_fp_control)); + if ((cpu_state.old_fp_control >> 22) & 3) + fatal("VFP not in nearest rounding mode\n"); } -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - if (mode < 0 || mode > 3) - fatal("codegen_set_rounding_mode - invalid mode\n"); - cpu_state.new_fp_control = mode << 2; + if (mode < 0 || mode > 3) + fatal("codegen_set_rounding_mode - invalid mode\n"); + cpu_state.new_fp_control = mode << 2; } /*R10 - cpu_state*/ -void codegen_backend_prologue(codeblock_t *block) +void +codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; + block_pos = BLOCK_START; - /*Entry code*/ + /*Entry code*/ - host_arm_STMDB_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_LR); - host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_MOV_IMM(block, REG_CPUSTATE, (uint32_t)&cpu_state); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); - host_arm_STR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - } + host_arm_STMDB_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_LR); + host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_MOV_IMM(block, REG_CPUSTATE, (uint32_t) &cpu_state); + if (block->flags & CODEBLOCK_HAS_FPU) { + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); + host_arm_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); + host_arm_STR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + } } -void codegen_backend_epilogue(codeblock_t *block) +void +codegen_backend_epilogue(codeblock_t *block) { - host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); - codegen_allocator_clean_blocks(block->head_mem_block); + codegen_allocator_clean_blocks(block->head_mem_block); } #endif diff --git a/src/codegen_new/codegen_backend_arm.h b/src/codegen_new/codegen_backend_arm.h index 8b8936a98..a3e236d4e 100644 --- a/src/codegen_new/codegen_backend_arm.h +++ b/src/codegen_new/codegen_backend_arm.h @@ -1,15 +1,15 @@ #include "codegen_backend_arm_defs.h" -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff #define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) -#define BLOCK_MAX 0x3c0 +#define BLOCK_MAX 0x3c0 void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); diff --git a/src/codegen_new/codegen_backend_arm64.c b/src/codegen_new/codegen_backend_arm64.c index ce1082d0a..48d949406 100644 --- a/src/codegen_new/codegen_backend_arm64.c +++ b/src/codegen_new/codegen_backend_arm64.c @@ -1,28 +1,28 @@ #if defined __aarch64__ || defined _M_ARM64 -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm64_defs.h" -#include "codegen_backend_arm64_ops.h" -#include "codegen_reg.h" -#include "x86.h" -#include "x87.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm64_defs.h" +# include "codegen_backend_arm64_ops.h" +# include "codegen_reg.h" +# include "x86.h" +# include "x87.h" -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#include -#endif -#include +# if defined(__linux__) || defined(__APPLE__) +# include +# include +# endif +# if defined WIN32 || defined _WIN32 || defined _WIN32 +# include +# endif +# include void *codegen_mem_load_byte; void *codegen_mem_load_word; @@ -44,334 +44,335 @@ void *codegen_fp_round_quad; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - {REG_X19, 0}, - {REG_X20, 0}, - {REG_X21, 0}, - {REG_X22, 0}, - {REG_X23, 0}, - {REG_X24, 0}, - {REG_X25, 0}, - {REG_X26, 0}, - {REG_X27, 0}, - {REG_X28, 0} +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + {REG_X19, 0}, + { REG_X20, 0}, + { REG_X21, 0}, + { REG_X22, 0}, + { REG_X23, 0}, + { REG_X24, 0}, + { REG_X25, 0}, + { REG_X26, 0}, + { REG_X27, 0}, + { REG_X28, 0} }; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ - {REG_V8, 0}, - {REG_V9, 0}, - {REG_V10, 0}, - {REG_V11, 0}, - {REG_V12, 0}, - {REG_V13, 0}, - {REG_V14, 0}, - {REG_V15, 0} +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { + {REG_V8, 0}, + { REG_V9, 0}, + { REG_V10, 0}, + { REG_V11, 0}, + { REG_V12, 0}, + { REG_V13, 0}, + { REG_V14, 0}, + { REG_V15, 0} }; -static void build_load_routine(codeblock_t *block, int size, int is_float) +static void +build_load_routine(codeblock_t *block, int size, int is_float) { - uint32_t *branch_offset; - uint32_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - W0 = address - Out - W0 = data, W1 = abrt*/ - /*MOV W1, W0, LSR #12 - MOV X2, #readlookup2 - LDR X1, [X2, X1, LSL #3] - CMP X1, #-1 - BEQ + - LDRB W0, [X1, X0] - MOV W1, #0 - RET - * STP X29, X30, [SP, #-16] - BL readmembl - LDRB R1, cpu_state.abrt - LDP X29, X30, [SP, #-16] - RET - */ - codegen_alloc(block, 80); - host_arm64_MOV_REG_LSR(block, REG_W1, REG_W0, 12); - host_arm64_MOVX_IMM(block, REG_X2, (uint64_t)readlookup2); - host_arm64_LDRX_REG_LSL3(block, REG_X1, REG_X2, REG_X1); - if (size != 1) - { - host_arm64_TST_IMM(block, REG_W0, size-1); - misaligned_offset = host_arm64_BNE_(block); - } - host_arm64_CMPX_IMM(block, REG_X1, -1); - branch_offset = host_arm64_BEQ_(block); - if (size == 1 && !is_float) - host_arm64_LDRB_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 2 && !is_float) - host_arm64_LDRH_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 4 && !is_float) - host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 4 && is_float) - host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0); - else if (size == 8) - host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0); - host_arm64_MOVZ_IMM(block, REG_W1, 0); - host_arm64_RET(block, REG_X30); + /*In - W0 = address + Out - W0 = data, W1 = abrt*/ + /*MOV W1, W0, LSR #12 + MOV X2, #readlookup2 + LDR X1, [X2, X1, LSL #3] + CMP X1, #-1 + BEQ + + LDRB W0, [X1, X0] + MOV W1, #0 + RET + * STP X29, X30, [SP, #-16] + BL readmembl + LDRB R1, cpu_state.abrt + LDP X29, X30, [SP, #-16] + RET + */ + codegen_alloc(block, 80); + host_arm64_MOV_REG_LSR(block, REG_W1, REG_W0, 12); + host_arm64_MOVX_IMM(block, REG_X2, (uint64_t) readlookup2); + host_arm64_LDRX_REG_LSL3(block, REG_X1, REG_X2, REG_X1); + if (size != 1) { + host_arm64_TST_IMM(block, REG_W0, size - 1); + misaligned_offset = host_arm64_BNE_(block); + } + host_arm64_CMPX_IMM(block, REG_X1, -1); + branch_offset = host_arm64_BEQ_(block); + if (size == 1 && !is_float) + host_arm64_LDRB_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 2 && !is_float) + host_arm64_LDRH_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 4 && !is_float) + host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 4 && is_float) + host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0); + else if (size == 8) + host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0); + host_arm64_MOVZ_IMM(block, REG_W1, 0); + host_arm64_RET(block, REG_X30); - host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); - if (size != 1) - host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); - if (size == 1) - host_arm64_call(block, (void *)readmembl); - else if (size == 2) - host_arm64_call(block, (void *)readmemwl); - else if (size == 4) - host_arm64_call(block, (void *)readmemll); - else if (size == 8) - host_arm64_call(block, (void *)readmemql); - else - fatal("build_load_routine - unknown size %i\n", size); - codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); - if (size == 4 && is_float) - host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0); - else if (size == 8) - host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); + if (size != 1) + host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + if (size == 1) + host_arm64_call(block, (void *) readmembl); + else if (size == 2) + host_arm64_call(block, (void *) readmemwl); + else if (size == 4) + host_arm64_call(block, (void *) readmemll); + else if (size == 8) + host_arm64_call(block, (void *) readmemql); + else + fatal("build_load_routine - unknown size %i\n", size); + codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); + if (size == 4 && is_float) + host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0); + else if (size == 8) + host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); } -static void build_store_routine(codeblock_t *block, int size, int is_float) +static void +build_store_routine(codeblock_t *block, int size, int is_float) { - uint32_t *branch_offset; - uint32_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - R0 = address, R1 = data - Out - R1 = abrt*/ - /*MOV W2, W0, LSR #12 - MOV X3, #writelookup2 - LDR X2, [X3, X2, LSL #3] - CMP X2, #-1 - BEQ + - STRB W1, [X2, X0] - MOV W1, #0 - RET - * STP X29, X30, [SP, #-16] - BL writemembl - LDRB R1, cpu_state.abrt - LDP X29, X30, [SP, #-16] - RET - */ - codegen_alloc(block, 80); - host_arm64_MOV_REG_LSR(block, REG_W2, REG_W0, 12); - host_arm64_MOVX_IMM(block, REG_X3, (uint64_t)writelookup2); - host_arm64_LDRX_REG_LSL3(block, REG_X2, REG_X3, REG_X2); - if (size != 1) - { - host_arm64_TST_IMM(block, REG_W0, size-1); - misaligned_offset = host_arm64_BNE_(block); - } - host_arm64_CMPX_IMM(block, REG_X2, -1); - branch_offset = host_arm64_BEQ_(block); - if (size == 1 && !is_float) - host_arm64_STRB_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 2 && !is_float) - host_arm64_STRH_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 4 && !is_float) - host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 4 && is_float) - host_arm64_STR_REG_F32(block, REG_V_TEMP, REG_X2, REG_X0); - else if (size == 8) - host_arm64_STR_REG_F64(block, REG_V_TEMP, REG_X2, REG_X0); - host_arm64_MOVZ_IMM(block, REG_X1, 0); - host_arm64_RET(block, REG_X30); + /*In - R0 = address, R1 = data + Out - R1 = abrt*/ + /*MOV W2, W0, LSR #12 + MOV X3, #writelookup2 + LDR X2, [X3, X2, LSL #3] + CMP X2, #-1 + BEQ + + STRB W1, [X2, X0] + MOV W1, #0 + RET + * STP X29, X30, [SP, #-16] + BL writemembl + LDRB R1, cpu_state.abrt + LDP X29, X30, [SP, #-16] + RET + */ + codegen_alloc(block, 80); + host_arm64_MOV_REG_LSR(block, REG_W2, REG_W0, 12); + host_arm64_MOVX_IMM(block, REG_X3, (uint64_t) writelookup2); + host_arm64_LDRX_REG_LSL3(block, REG_X2, REG_X3, REG_X2); + if (size != 1) { + host_arm64_TST_IMM(block, REG_W0, size - 1); + misaligned_offset = host_arm64_BNE_(block); + } + host_arm64_CMPX_IMM(block, REG_X2, -1); + branch_offset = host_arm64_BEQ_(block); + if (size == 1 && !is_float) + host_arm64_STRB_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 2 && !is_float) + host_arm64_STRH_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 4 && !is_float) + host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 4 && is_float) + host_arm64_STR_REG_F32(block, REG_V_TEMP, REG_X2, REG_X0); + else if (size == 8) + host_arm64_STR_REG_F64(block, REG_V_TEMP, REG_X2, REG_X0); + host_arm64_MOVZ_IMM(block, REG_X1, 0); + host_arm64_RET(block, REG_X30); - host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); - if (size != 1) - host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); - if (size == 4 && is_float) - host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); - else if (size == 8) - host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); - if (size == 1) - host_arm64_call(block, (void *)writemembl); - else if (size == 2) - host_arm64_call(block, (void *)writememwl); - else if (size == 4) - host_arm64_call(block, (void *)writememll); - else if (size == 8) - host_arm64_call(block, (void *)writememql); - else - fatal("build_store_routine - unknown size %i\n", size); - codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); + if (size != 1) + host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + if (size == 4 && is_float) + host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); + else if (size == 8) + host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); + if (size == 1) + host_arm64_call(block, (void *) writemembl); + else if (size == 2) + host_arm64_call(block, (void *) writememwl); + else if (size == 4) + host_arm64_call(block, (void *) writememll); + else if (size == 8) + host_arm64_call(block, (void *) writememql); + else + fatal("build_store_routine - unknown size %i\n", size); + codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); } -static void build_loadstore_routines(codeblock_t *block) +static void +build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &block_write_data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &block_write_data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &block_write_data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &block_write_data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &block_write_data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &block_write_data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &block_write_data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &block_write_data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &block_write_data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &block_write_data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &block_write_data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &block_write_data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &block_write_data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &block_write_data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &block_write_data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &block_write_data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &block_write_data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &block_write_data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &block_write_data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &block_write_data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &block_write_data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &block_write_data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &block_write_data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &block_write_data[block_pos]; + build_store_routine(block, 8, 1); } -static void build_fp_round_routine(codeblock_t *block, int is_quad) +static void +build_fp_round_routine(codeblock_t *block, int is_quad) { - uint64_t *jump_table; + uint64_t *jump_table; - codegen_alloc(block, 80); - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); - host_arm64_ADR(block, REG_TEMP2, 12); - host_arm64_LDR_REG_X(block, REG_TEMP2, REG_TEMP2, REG_TEMP); - host_arm64_BR(block, REG_TEMP2); + codegen_alloc(block, 80); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.new_fp_control - (uintptr_t) &cpu_state); + host_arm64_ADR(block, REG_TEMP2, 12); + host_arm64_LDR_REG_X(block, REG_TEMP2, REG_TEMP2, REG_TEMP); + host_arm64_BR(block, REG_TEMP2); - jump_table = (uint64_t *)&block_write_data[block_pos]; - block_pos += 4*8; + jump_table = (uint64_t *) &block_write_data[block_pos]; + block_pos += 4 * 8; - jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even - if (is_quad) - host_arm64_FCVTNS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTNS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_NEAREST] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // tie even + if (is_quad) + host_arm64_FCVTNS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTNS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //pos inf - if (is_quad) - host_arm64_FCVTPS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTPS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_UP] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // pos inf + if (is_quad) + host_arm64_FCVTPS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTPS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //neg inf - if (is_quad) - host_arm64_FCVTMS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTMS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_DOWN] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // neg inf + if (is_quad) + host_arm64_FCVTMS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTMS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //zero - if (is_quad) - host_arm64_FCVTZS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTZS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_CHOP] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // zero + if (is_quad) + host_arm64_FCVTZS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTZS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); } -void codegen_backend_init() +void +codegen_backend_init(void) { - codeblock_t *block; - int c; + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - { - codeblock[c].pc = BLOCK_PC_INVALID; - } + for (c = 0; c < BLOCK_SIZE; c++) { + codeblock[c].pc = BLOCK_PC_INVALID; + } - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block_write_data = block->data; - build_loadstore_routines(block); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(block); - codegen_fp_round = &block_write_data[block_pos]; - build_fp_round_routine(block, 0); - codegen_fp_round_quad = &block_write_data[block_pos]; - build_fp_round_routine(block, 1); + codegen_fp_round = &block_write_data[block_pos]; + build_fp_round_routine(block, 0); + codegen_fp_round_quad = &block_write_data[block_pos]; + build_fp_round_routine(block, 1); - codegen_alloc(block, 80); - codegen_gpf_rout = &block_write_data[block_pos]; - host_arm64_mov_imm(block, REG_ARG0, 0); - host_arm64_mov_imm(block, REG_ARG1, 0); - host_arm64_call(block, (void *)x86gpf); + codegen_alloc(block, 80); + codegen_gpf_rout = &block_write_data[block_pos]; + host_arm64_mov_imm(block, REG_ARG0, 0); + host_arm64_mov_imm(block, REG_ARG1, 0); + host_arm64_call(block, (void *) x86gpf); - codegen_exit_rout = &block_write_data[block_pos]; - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); - host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + codegen_exit_rout = &block_write_data[block_pos]; + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); - block_write_data = NULL; + block_write_data = NULL; - codegen_allocator_clean_blocks(block->head_mem_block); + codegen_allocator_clean_blocks(block->head_mem_block); - asm("mrs %0, fpcr\n" - : "=r" (cpu_state.old_fp_control) - ); + asm("mrs %0, fpcr\n" + : "=r"(cpu_state.old_fp_control)); } -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - if (mode < 0 || mode > 3) - fatal("codegen_set_rounding_mode - invalid mode\n"); - cpu_state.new_fp_control = mode << 3; + if (mode < 0 || mode > 3) + fatal("codegen_set_rounding_mode - invalid mode\n"); + cpu_state.new_fp_control = mode << 3; } /*R10 - cpu_state*/ -void codegen_backend_prologue(codeblock_t *block) +void +codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; + block_pos = BLOCK_START; - /*Entry code*/ + /*Entry code*/ - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_XSP, -64); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_XSP, -64); - host_arm64_MOVX_IMM(block, REG_CPUSTATE, (uint64_t)&cpu_state); + host_arm64_MOVX_IMM(block, REG_CPUSTATE, (uint64_t) &cpu_state); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm64_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - } + if (block->flags & CODEBLOCK_HAS_FPU) { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); + host_arm64_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + } } -void codegen_backend_epilogue(codeblock_t *block) +void +codegen_backend_epilogue(codeblock_t *block) { - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); - host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); - codegen_allocator_clean_blocks(block->head_mem_block); + codegen_allocator_clean_blocks(block->head_mem_block); } #endif diff --git a/src/codegen_new/codegen_backend_arm64.h b/src/codegen_new/codegen_backend_arm64.h index 3e3d16575..bf3084f58 100644 --- a/src/codegen_new/codegen_backend_arm64.h +++ b/src/codegen_new/codegen_backend_arm64.h @@ -1,16 +1,15 @@ #include "codegen_backend_arm64_defs.h" -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff #define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) - -#define BLOCK_MAX 0x3c0 +#define HASH(l) ((l) &0x1ffff) +#define BLOCK_MAX 0x3c0 void host_arm64_BLR(codeblock_t *block, int addr_reg); void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest); diff --git a/src/codegen_new/codegen_backend_arm64_defs.h b/src/codegen_new/codegen_backend_arm64_defs.h index ac2d238da..c36f1c4a2 100644 --- a/src/codegen_new/codegen_backend_arm64_defs.h +++ b/src/codegen_new/codegen_backend_arm64_defs.h @@ -1,117 +1,117 @@ -#define REG_W0 0 -#define REG_W1 1 -#define REG_W2 2 -#define REG_W3 3 -#define REG_W4 4 -#define REG_W5 5 -#define REG_W6 6 -#define REG_W7 7 -#define REG_W8 8 -#define REG_W9 9 -#define REG_W10 10 -#define REG_W11 11 -#define REG_W12 12 -#define REG_W13 13 -#define REG_W14 14 -#define REG_W15 15 -#define REG_W16 16 -#define REG_W17 17 -#define REG_W18 18 -#define REG_W19 19 -#define REG_W20 20 -#define REG_W21 21 -#define REG_W22 22 -#define REG_W23 23 -#define REG_W24 24 -#define REG_W25 25 -#define REG_W26 26 -#define REG_W27 27 -#define REG_W28 28 -#define REG_W29 29 -#define REG_W30 30 -#define REG_WZR 31 +#define REG_W0 0 +#define REG_W1 1 +#define REG_W2 2 +#define REG_W3 3 +#define REG_W4 4 +#define REG_W5 5 +#define REG_W6 6 +#define REG_W7 7 +#define REG_W8 8 +#define REG_W9 9 +#define REG_W10 10 +#define REG_W11 11 +#define REG_W12 12 +#define REG_W13 13 +#define REG_W14 14 +#define REG_W15 15 +#define REG_W16 16 +#define REG_W17 17 +#define REG_W18 18 +#define REG_W19 19 +#define REG_W20 20 +#define REG_W21 21 +#define REG_W22 22 +#define REG_W23 23 +#define REG_W24 24 +#define REG_W25 25 +#define REG_W26 26 +#define REG_W27 27 +#define REG_W28 28 +#define REG_W29 29 +#define REG_W30 30 +#define REG_WZR 31 -#define REG_X0 0 -#define REG_X1 1 -#define REG_X2 2 -#define REG_X3 3 -#define REG_X4 4 -#define REG_X5 5 -#define REG_X6 6 -#define REG_X7 7 -#define REG_X8 8 -#define REG_X9 9 -#define REG_X10 10 -#define REG_X11 11 -#define REG_X12 12 -#define REG_X13 13 -#define REG_X14 14 -#define REG_X15 15 -#define REG_X16 16 -#define REG_X17 17 -#define REG_X18 18 -#define REG_X19 19 -#define REG_X20 20 -#define REG_X21 21 -#define REG_X22 22 -#define REG_X23 23 -#define REG_X24 24 -#define REG_X25 25 -#define REG_X26 26 -#define REG_X27 27 -#define REG_X28 28 -#define REG_X29 29 -#define REG_X30 30 -#define REG_XZR 31 +#define REG_X0 0 +#define REG_X1 1 +#define REG_X2 2 +#define REG_X3 3 +#define REG_X4 4 +#define REG_X5 5 +#define REG_X6 6 +#define REG_X7 7 +#define REG_X8 8 +#define REG_X9 9 +#define REG_X10 10 +#define REG_X11 11 +#define REG_X12 12 +#define REG_X13 13 +#define REG_X14 14 +#define REG_X15 15 +#define REG_X16 16 +#define REG_X17 17 +#define REG_X18 18 +#define REG_X19 19 +#define REG_X20 20 +#define REG_X21 21 +#define REG_X22 22 +#define REG_X23 23 +#define REG_X24 24 +#define REG_X25 25 +#define REG_X26 26 +#define REG_X27 27 +#define REG_X28 28 +#define REG_X29 29 +#define REG_X30 30 +#define REG_XZR 31 -#define REG_V0 0 -#define REG_V1 1 -#define REG_V2 2 -#define REG_V3 3 -#define REG_V4 4 -#define REG_V5 5 -#define REG_V6 6 -#define REG_V7 7 -#define REG_V8 8 -#define REG_V9 9 -#define REG_V10 10 -#define REG_V11 11 -#define REG_V12 12 -#define REG_V13 13 -#define REG_V14 14 -#define REG_V15 15 -#define REG_V16 16 -#define REG_V17 17 -#define REG_V18 18 -#define REG_V19 19 -#define REG_V20 20 -#define REG_V21 21 -#define REG_V22 22 -#define REG_V23 23 -#define REG_V24 24 -#define REG_V25 25 -#define REG_V26 26 -#define REG_V27 27 -#define REG_V28 28 -#define REG_V29 29 -#define REG_V30 30 -#define REG_V31 31 +#define REG_V0 0 +#define REG_V1 1 +#define REG_V2 2 +#define REG_V3 3 +#define REG_V4 4 +#define REG_V5 5 +#define REG_V6 6 +#define REG_V7 7 +#define REG_V8 8 +#define REG_V9 9 +#define REG_V10 10 +#define REG_V11 11 +#define REG_V12 12 +#define REG_V13 13 +#define REG_V14 14 +#define REG_V15 15 +#define REG_V16 16 +#define REG_V17 17 +#define REG_V18 18 +#define REG_V19 19 +#define REG_V20 20 +#define REG_V21 21 +#define REG_V22 22 +#define REG_V23 23 +#define REG_V24 24 +#define REG_V25 25 +#define REG_V26 26 +#define REG_V27 27 +#define REG_V28 28 +#define REG_V29 29 +#define REG_V30 30 +#define REG_V31 31 -#define REG_XSP 31 +#define REG_XSP 31 -#define REG_ARG0 REG_X0 -#define REG_ARG1 REG_X1 -#define REG_ARG2 REG_X2 -#define REG_ARG3 REG_X3 +#define REG_ARG0 REG_X0 +#define REG_ARG1 REG_X1 +#define REG_ARG2 REG_X2 +#define REG_ARG3 REG_X3 -#define REG_CPUSTATE REG_X29 +#define REG_CPUSTATE REG_X29 -#define REG_TEMP REG_X7 -#define REG_TEMP2 REG_X6 +#define REG_TEMP REG_X7 +#define REG_TEMP2 REG_X6 -#define REG_V_TEMP REG_V0 +#define REG_V_TEMP REG_V0 -#define CODEGEN_HOST_REGS 10 +#define CODEGEN_HOST_REGS 10 #define CODEGEN_HOST_FP_REGS 8 extern void *codegen_mem_load_byte; diff --git a/src/codegen_new/codegen_backend_arm64_imm.c b/src/codegen_new/codegen_backend_arm64_imm.c index 0362b71d6..5e1e1038f 100644 --- a/src/codegen_new/codegen_backend_arm64_imm.c +++ b/src/codegen_new/codegen_backend_arm64_imm.c @@ -5,1326 +5,1325 @@ All valid values are in the table below, which we perform a binary search over*/ #define IMM_NR 1302 -static uint32_t imm_table[][2] = -{ - {0x800, 0x00000001}, - {0xfc0, 0x00000002}, - {0x801, 0x00000003}, - {0xf80, 0x00000004}, - {0xfc1, 0x00000006}, - {0x802, 0x00000007}, - {0xf40, 0x00000008}, - {0xf81, 0x0000000c}, - {0xfc2, 0x0000000e}, - {0x803, 0x0000000f}, - {0xf00, 0x00000010}, - {0xf41, 0x00000018}, - {0xf82, 0x0000001c}, - {0xfc3, 0x0000001e}, - {0x804, 0x0000001f}, - {0xec0, 0x00000020}, - {0xf01, 0x00000030}, - {0xf42, 0x00000038}, - {0xf83, 0x0000003c}, - {0xfc4, 0x0000003e}, - {0x805, 0x0000003f}, - {0xe80, 0x00000040}, - {0xec1, 0x00000060}, - {0xf02, 0x00000070}, - {0xf43, 0x00000078}, - {0xf84, 0x0000007c}, - {0xfc5, 0x0000007e}, - {0x806, 0x0000007f}, - {0xe40, 0x00000080}, - {0xe81, 0x000000c0}, - {0xec2, 0x000000e0}, - {0xf03, 0x000000f0}, - {0xf44, 0x000000f8}, - {0xf85, 0x000000fc}, - {0xfc6, 0x000000fe}, - {0x807, 0x000000ff}, - {0xe00, 0x00000100}, - {0xe41, 0x00000180}, - {0xe82, 0x000001c0}, - {0xec3, 0x000001e0}, - {0xf04, 0x000001f0}, - {0xf45, 0x000001f8}, - {0xf86, 0x000001fc}, - {0xfc7, 0x000001fe}, - {0x808, 0x000001ff}, - {0xdc0, 0x00000200}, - {0xe01, 0x00000300}, - {0xe42, 0x00000380}, - {0xe83, 0x000003c0}, - {0xec4, 0x000003e0}, - {0xf05, 0x000003f0}, - {0xf46, 0x000003f8}, - {0xf87, 0x000003fc}, - {0xfc8, 0x000003fe}, - {0x809, 0x000003ff}, - {0xd80, 0x00000400}, - {0xdc1, 0x00000600}, - {0xe02, 0x00000700}, - {0xe43, 0x00000780}, - {0xe84, 0x000007c0}, - {0xec5, 0x000007e0}, - {0xf06, 0x000007f0}, - {0xf47, 0x000007f8}, - {0xf88, 0x000007fc}, - {0xfc9, 0x000007fe}, - {0x80a, 0x000007ff}, - {0xd40, 0x00000800}, - {0xd81, 0x00000c00}, - {0xdc2, 0x00000e00}, - {0xe03, 0x00000f00}, - {0xe44, 0x00000f80}, - {0xe85, 0x00000fc0}, - {0xec6, 0x00000fe0}, - {0xf07, 0x00000ff0}, - {0xf48, 0x00000ff8}, - {0xf89, 0x00000ffc}, - {0xfca, 0x00000ffe}, - {0x80b, 0x00000fff}, - {0xd00, 0x00001000}, - {0xd41, 0x00001800}, - {0xd82, 0x00001c00}, - {0xdc3, 0x00001e00}, - {0xe04, 0x00001f00}, - {0xe45, 0x00001f80}, - {0xe86, 0x00001fc0}, - {0xec7, 0x00001fe0}, - {0xf08, 0x00001ff0}, - {0xf49, 0x00001ff8}, - {0xf8a, 0x00001ffc}, - {0xfcb, 0x00001ffe}, - {0x80c, 0x00001fff}, - {0xcc0, 0x00002000}, - {0xd01, 0x00003000}, - {0xd42, 0x00003800}, - {0xd83, 0x00003c00}, - {0xdc4, 0x00003e00}, - {0xe05, 0x00003f00}, - {0xe46, 0x00003f80}, - {0xe87, 0x00003fc0}, - {0xec8, 0x00003fe0}, - {0xf09, 0x00003ff0}, - {0xf4a, 0x00003ff8}, - {0xf8b, 0x00003ffc}, - {0xfcc, 0x00003ffe}, - {0x80d, 0x00003fff}, - {0xc80, 0x00004000}, - {0xcc1, 0x00006000}, - {0xd02, 0x00007000}, - {0xd43, 0x00007800}, - {0xd84, 0x00007c00}, - {0xdc5, 0x00007e00}, - {0xe06, 0x00007f00}, - {0xe47, 0x00007f80}, - {0xe88, 0x00007fc0}, - {0xec9, 0x00007fe0}, - {0xf0a, 0x00007ff0}, - {0xf4b, 0x00007ff8}, - {0xf8c, 0x00007ffc}, - {0xfcd, 0x00007ffe}, - {0x80e, 0x00007fff}, - {0xc40, 0x00008000}, - {0xc81, 0x0000c000}, - {0xcc2, 0x0000e000}, - {0xd03, 0x0000f000}, - {0xd44, 0x0000f800}, - {0xd85, 0x0000fc00}, - {0xdc6, 0x0000fe00}, - {0xe07, 0x0000ff00}, - {0xe48, 0x0000ff80}, - {0xe89, 0x0000ffc0}, - {0xeca, 0x0000ffe0}, - {0xf0b, 0x0000fff0}, - {0xf4c, 0x0000fff8}, - {0xf8d, 0x0000fffc}, - {0xfce, 0x0000fffe}, - {0x80f, 0x0000ffff}, - {0xc00, 0x00010000}, - {0xc20, 0x00010001}, - {0xc41, 0x00018000}, - {0xc82, 0x0001c000}, - {0xcc3, 0x0001e000}, - {0xd04, 0x0001f000}, - {0xd45, 0x0001f800}, - {0xd86, 0x0001fc00}, - {0xdc7, 0x0001fe00}, - {0xe08, 0x0001ff00}, - {0xe49, 0x0001ff80}, - {0xe8a, 0x0001ffc0}, - {0xecb, 0x0001ffe0}, - {0xf0c, 0x0001fff0}, - {0xf4d, 0x0001fff8}, - {0xf8e, 0x0001fffc}, - {0xfcf, 0x0001fffe}, - {0x810, 0x0001ffff}, - {0xbc0, 0x00020000}, - {0xfe0, 0x00020002}, - {0xc01, 0x00030000}, - {0xc21, 0x00030003}, - {0xc42, 0x00038000}, - {0xc83, 0x0003c000}, - {0xcc4, 0x0003e000}, - {0xd05, 0x0003f000}, - {0xd46, 0x0003f800}, - {0xd87, 0x0003fc00}, - {0xdc8, 0x0003fe00}, - {0xe09, 0x0003ff00}, - {0xe4a, 0x0003ff80}, - {0xe8b, 0x0003ffc0}, - {0xecc, 0x0003ffe0}, - {0xf0d, 0x0003fff0}, - {0xf4e, 0x0003fff8}, - {0xf8f, 0x0003fffc}, - {0xfd0, 0x0003fffe}, - {0x811, 0x0003ffff}, - {0xb80, 0x00040000}, - {0xfa0, 0x00040004}, - {0xbc1, 0x00060000}, - {0xfe1, 0x00060006}, - {0xc02, 0x00070000}, - {0xc22, 0x00070007}, - {0xc43, 0x00078000}, - {0xc84, 0x0007c000}, - {0xcc5, 0x0007e000}, - {0xd06, 0x0007f000}, - {0xd47, 0x0007f800}, - {0xd88, 0x0007fc00}, - {0xdc9, 0x0007fe00}, - {0xe0a, 0x0007ff00}, - {0xe4b, 0x0007ff80}, - {0xe8c, 0x0007ffc0}, - {0xecd, 0x0007ffe0}, - {0xf0e, 0x0007fff0}, - {0xf4f, 0x0007fff8}, - {0xf90, 0x0007fffc}, - {0xfd1, 0x0007fffe}, - {0x812, 0x0007ffff}, - {0xb40, 0x00080000}, - {0xf60, 0x00080008}, - {0xb81, 0x000c0000}, - {0xfa1, 0x000c000c}, - {0xbc2, 0x000e0000}, - {0xfe2, 0x000e000e}, - {0xc03, 0x000f0000}, - {0xc23, 0x000f000f}, - {0xc44, 0x000f8000}, - {0xc85, 0x000fc000}, - {0xcc6, 0x000fe000}, - {0xd07, 0x000ff000}, - {0xd48, 0x000ff800}, - {0xd89, 0x000ffc00}, - {0xdca, 0x000ffe00}, - {0xe0b, 0x000fff00}, - {0xe4c, 0x000fff80}, - {0xe8d, 0x000fffc0}, - {0xece, 0x000fffe0}, - {0xf0f, 0x000ffff0}, - {0xf50, 0x000ffff8}, - {0xf91, 0x000ffffc}, - {0xfd2, 0x000ffffe}, - {0x813, 0x000fffff}, - {0xb00, 0x00100000}, - {0xf20, 0x00100010}, - {0xb41, 0x00180000}, - {0xf61, 0x00180018}, - {0xb82, 0x001c0000}, - {0xfa2, 0x001c001c}, - {0xbc3, 0x001e0000}, - {0xfe3, 0x001e001e}, - {0xc04, 0x001f0000}, - {0xc24, 0x001f001f}, - {0xc45, 0x001f8000}, - {0xc86, 0x001fc000}, - {0xcc7, 0x001fe000}, - {0xd08, 0x001ff000}, - {0xd49, 0x001ff800}, - {0xd8a, 0x001ffc00}, - {0xdcb, 0x001ffe00}, - {0xe0c, 0x001fff00}, - {0xe4d, 0x001fff80}, - {0xe8e, 0x001fffc0}, - {0xecf, 0x001fffe0}, - {0xf10, 0x001ffff0}, - {0xf51, 0x001ffff8}, - {0xf92, 0x001ffffc}, - {0xfd3, 0x001ffffe}, - {0x814, 0x001fffff}, - {0xac0, 0x00200000}, - {0xee0, 0x00200020}, - {0xb01, 0x00300000}, - {0xf21, 0x00300030}, - {0xb42, 0x00380000}, - {0xf62, 0x00380038}, - {0xb83, 0x003c0000}, - {0xfa3, 0x003c003c}, - {0xbc4, 0x003e0000}, - {0xfe4, 0x003e003e}, - {0xc05, 0x003f0000}, - {0xc25, 0x003f003f}, - {0xc46, 0x003f8000}, - {0xc87, 0x003fc000}, - {0xcc8, 0x003fe000}, - {0xd09, 0x003ff000}, - {0xd4a, 0x003ff800}, - {0xd8b, 0x003ffc00}, - {0xdcc, 0x003ffe00}, - {0xe0d, 0x003fff00}, - {0xe4e, 0x003fff80}, - {0xe8f, 0x003fffc0}, - {0xed0, 0x003fffe0}, - {0xf11, 0x003ffff0}, - {0xf52, 0x003ffff8}, - {0xf93, 0x003ffffc}, - {0xfd4, 0x003ffffe}, - {0x815, 0x003fffff}, - {0xa80, 0x00400000}, - {0xea0, 0x00400040}, - {0xac1, 0x00600000}, - {0xee1, 0x00600060}, - {0xb02, 0x00700000}, - {0xf22, 0x00700070}, - {0xb43, 0x00780000}, - {0xf63, 0x00780078}, - {0xb84, 0x007c0000}, - {0xfa4, 0x007c007c}, - {0xbc5, 0x007e0000}, - {0xfe5, 0x007e007e}, - {0xc06, 0x007f0000}, - {0xc26, 0x007f007f}, - {0xc47, 0x007f8000}, - {0xc88, 0x007fc000}, - {0xcc9, 0x007fe000}, - {0xd0a, 0x007ff000}, - {0xd4b, 0x007ff800}, - {0xd8c, 0x007ffc00}, - {0xdcd, 0x007ffe00}, - {0xe0e, 0x007fff00}, - {0xe4f, 0x007fff80}, - {0xe90, 0x007fffc0}, - {0xed1, 0x007fffe0}, - {0xf12, 0x007ffff0}, - {0xf53, 0x007ffff8}, - {0xf94, 0x007ffffc}, - {0xfd5, 0x007ffffe}, - {0x816, 0x007fffff}, - {0xa40, 0x00800000}, - {0xe60, 0x00800080}, - {0xa81, 0x00c00000}, - {0xea1, 0x00c000c0}, - {0xac2, 0x00e00000}, - {0xee2, 0x00e000e0}, - {0xb03, 0x00f00000}, - {0xf23, 0x00f000f0}, - {0xb44, 0x00f80000}, - {0xf64, 0x00f800f8}, - {0xb85, 0x00fc0000}, - {0xfa5, 0x00fc00fc}, - {0xbc6, 0x00fe0000}, - {0xfe6, 0x00fe00fe}, - {0xc07, 0x00ff0000}, - {0xc27, 0x00ff00ff}, - {0xc48, 0x00ff8000}, - {0xc89, 0x00ffc000}, - {0xcca, 0x00ffe000}, - {0xd0b, 0x00fff000}, - {0xd4c, 0x00fff800}, - {0xd8d, 0x00fffc00}, - {0xdce, 0x00fffe00}, - {0xe0f, 0x00ffff00}, - {0xe50, 0x00ffff80}, - {0xe91, 0x00ffffc0}, - {0xed2, 0x00ffffe0}, - {0xf13, 0x00fffff0}, - {0xf54, 0x00fffff8}, - {0xf95, 0x00fffffc}, - {0xfd6, 0x00fffffe}, - {0x817, 0x00ffffff}, - {0xa00, 0x01000000}, - {0xe20, 0x01000100}, - {0xe30, 0x01010101}, - {0xa41, 0x01800000}, - {0xe61, 0x01800180}, - {0xa82, 0x01c00000}, - {0xea2, 0x01c001c0}, - {0xac3, 0x01e00000}, - {0xee3, 0x01e001e0}, - {0xb04, 0x01f00000}, - {0xf24, 0x01f001f0}, - {0xb45, 0x01f80000}, - {0xf65, 0x01f801f8}, - {0xb86, 0x01fc0000}, - {0xfa6, 0x01fc01fc}, - {0xbc7, 0x01fe0000}, - {0xfe7, 0x01fe01fe}, - {0xc08, 0x01ff0000}, - {0xc28, 0x01ff01ff}, - {0xc49, 0x01ff8000}, - {0xc8a, 0x01ffc000}, - {0xccb, 0x01ffe000}, - {0xd0c, 0x01fff000}, - {0xd4d, 0x01fff800}, - {0xd8e, 0x01fffc00}, - {0xdcf, 0x01fffe00}, - {0xe10, 0x01ffff00}, - {0xe51, 0x01ffff80}, - {0xe92, 0x01ffffc0}, - {0xed3, 0x01ffffe0}, - {0xf14, 0x01fffff0}, - {0xf55, 0x01fffff8}, - {0xf96, 0x01fffffc}, - {0xfd7, 0x01fffffe}, - {0x818, 0x01ffffff}, - {0x9c0, 0x02000000}, - {0xde0, 0x02000200}, - {0xff0, 0x02020202}, - {0xa01, 0x03000000}, - {0xe21, 0x03000300}, - {0xe31, 0x03030303}, - {0xa42, 0x03800000}, - {0xe62, 0x03800380}, - {0xa83, 0x03c00000}, - {0xea3, 0x03c003c0}, - {0xac4, 0x03e00000}, - {0xee4, 0x03e003e0}, - {0xb05, 0x03f00000}, - {0xf25, 0x03f003f0}, - {0xb46, 0x03f80000}, - {0xf66, 0x03f803f8}, - {0xb87, 0x03fc0000}, - {0xfa7, 0x03fc03fc}, - {0xbc8, 0x03fe0000}, - {0xfe8, 0x03fe03fe}, - {0xc09, 0x03ff0000}, - {0xc29, 0x03ff03ff}, - {0xc4a, 0x03ff8000}, - {0xc8b, 0x03ffc000}, - {0xccc, 0x03ffe000}, - {0xd0d, 0x03fff000}, - {0xd4e, 0x03fff800}, - {0xd8f, 0x03fffc00}, - {0xdd0, 0x03fffe00}, - {0xe11, 0x03ffff00}, - {0xe52, 0x03ffff80}, - {0xe93, 0x03ffffc0}, - {0xed4, 0x03ffffe0}, - {0xf15, 0x03fffff0}, - {0xf56, 0x03fffff8}, - {0xf97, 0x03fffffc}, - {0xfd8, 0x03fffffe}, - {0x819, 0x03ffffff}, - {0x980, 0x04000000}, - {0xda0, 0x04000400}, - {0xfb0, 0x04040404}, - {0x9c1, 0x06000000}, - {0xde1, 0x06000600}, - {0xff1, 0x06060606}, - {0xa02, 0x07000000}, - {0xe22, 0x07000700}, - {0xe32, 0x07070707}, - {0xa43, 0x07800000}, - {0xe63, 0x07800780}, - {0xa84, 0x07c00000}, - {0xea4, 0x07c007c0}, - {0xac5, 0x07e00000}, - {0xee5, 0x07e007e0}, - {0xb06, 0x07f00000}, - {0xf26, 0x07f007f0}, - {0xb47, 0x07f80000}, - {0xf67, 0x07f807f8}, - {0xb88, 0x07fc0000}, - {0xfa8, 0x07fc07fc}, - {0xbc9, 0x07fe0000}, - {0xfe9, 0x07fe07fe}, - {0xc0a, 0x07ff0000}, - {0xc2a, 0x07ff07ff}, - {0xc4b, 0x07ff8000}, - {0xc8c, 0x07ffc000}, - {0xccd, 0x07ffe000}, - {0xd0e, 0x07fff000}, - {0xd4f, 0x07fff800}, - {0xd90, 0x07fffc00}, - {0xdd1, 0x07fffe00}, - {0xe12, 0x07ffff00}, - {0xe53, 0x07ffff80}, - {0xe94, 0x07ffffc0}, - {0xed5, 0x07ffffe0}, - {0xf16, 0x07fffff0}, - {0xf57, 0x07fffff8}, - {0xf98, 0x07fffffc}, - {0xfd9, 0x07fffffe}, - {0x81a, 0x07ffffff}, - {0x940, 0x08000000}, - {0xd60, 0x08000800}, - {0xf70, 0x08080808}, - {0x981, 0x0c000000}, - {0xda1, 0x0c000c00}, - {0xfb1, 0x0c0c0c0c}, - {0x9c2, 0x0e000000}, - {0xde2, 0x0e000e00}, - {0xff2, 0x0e0e0e0e}, - {0xa03, 0x0f000000}, - {0xe23, 0x0f000f00}, - {0xe33, 0x0f0f0f0f}, - {0xa44, 0x0f800000}, - {0xe64, 0x0f800f80}, - {0xa85, 0x0fc00000}, - {0xea5, 0x0fc00fc0}, - {0xac6, 0x0fe00000}, - {0xee6, 0x0fe00fe0}, - {0xb07, 0x0ff00000}, - {0xf27, 0x0ff00ff0}, - {0xb48, 0x0ff80000}, - {0xf68, 0x0ff80ff8}, - {0xb89, 0x0ffc0000}, - {0xfa9, 0x0ffc0ffc}, - {0xbca, 0x0ffe0000}, - {0xfea, 0x0ffe0ffe}, - {0xc0b, 0x0fff0000}, - {0xc2b, 0x0fff0fff}, - {0xc4c, 0x0fff8000}, - {0xc8d, 0x0fffc000}, - {0xcce, 0x0fffe000}, - {0xd0f, 0x0ffff000}, - {0xd50, 0x0ffff800}, - {0xd91, 0x0ffffc00}, - {0xdd2, 0x0ffffe00}, - {0xe13, 0x0fffff00}, - {0xe54, 0x0fffff80}, - {0xe95, 0x0fffffc0}, - {0xed6, 0x0fffffe0}, - {0xf17, 0x0ffffff0}, - {0xf58, 0x0ffffff8}, - {0xf99, 0x0ffffffc}, - {0xfda, 0x0ffffffe}, - {0x81b, 0x0fffffff}, - {0x900, 0x10000000}, - {0xd20, 0x10001000}, - {0xf30, 0x10101010}, - {0xf38, 0x11111111}, - {0x941, 0x18000000}, - {0xd61, 0x18001800}, - {0xf71, 0x18181818}, - {0x982, 0x1c000000}, - {0xda2, 0x1c001c00}, - {0xfb2, 0x1c1c1c1c}, - {0x9c3, 0x1e000000}, - {0xde3, 0x1e001e00}, - {0xff3, 0x1e1e1e1e}, - {0xa04, 0x1f000000}, - {0xe24, 0x1f001f00}, - {0xe34, 0x1f1f1f1f}, - {0xa45, 0x1f800000}, - {0xe65, 0x1f801f80}, - {0xa86, 0x1fc00000}, - {0xea6, 0x1fc01fc0}, - {0xac7, 0x1fe00000}, - {0xee7, 0x1fe01fe0}, - {0xb08, 0x1ff00000}, - {0xf28, 0x1ff01ff0}, - {0xb49, 0x1ff80000}, - {0xf69, 0x1ff81ff8}, - {0xb8a, 0x1ffc0000}, - {0xfaa, 0x1ffc1ffc}, - {0xbcb, 0x1ffe0000}, - {0xfeb, 0x1ffe1ffe}, - {0xc0c, 0x1fff0000}, - {0xc2c, 0x1fff1fff}, - {0xc4d, 0x1fff8000}, - {0xc8e, 0x1fffc000}, - {0xccf, 0x1fffe000}, - {0xd10, 0x1ffff000}, - {0xd51, 0x1ffff800}, - {0xd92, 0x1ffffc00}, - {0xdd3, 0x1ffffe00}, - {0xe14, 0x1fffff00}, - {0xe55, 0x1fffff80}, - {0xe96, 0x1fffffc0}, - {0xed7, 0x1fffffe0}, - {0xf18, 0x1ffffff0}, - {0xf59, 0x1ffffff8}, - {0xf9a, 0x1ffffffc}, - {0xfdb, 0x1ffffffe}, - {0x81c, 0x1fffffff}, - {0x8c0, 0x20000000}, - {0xce0, 0x20002000}, - {0xef0, 0x20202020}, - {0xff8, 0x22222222}, - {0x901, 0x30000000}, - {0xd21, 0x30003000}, - {0xf31, 0x30303030}, - {0xf39, 0x33333333}, - {0x942, 0x38000000}, - {0xd62, 0x38003800}, - {0xf72, 0x38383838}, - {0x983, 0x3c000000}, - {0xda3, 0x3c003c00}, - {0xfb3, 0x3c3c3c3c}, - {0x9c4, 0x3e000000}, - {0xde4, 0x3e003e00}, - {0xff4, 0x3e3e3e3e}, - {0xa05, 0x3f000000}, - {0xe25, 0x3f003f00}, - {0xe35, 0x3f3f3f3f}, - {0xa46, 0x3f800000}, - {0xe66, 0x3f803f80}, - {0xa87, 0x3fc00000}, - {0xea7, 0x3fc03fc0}, - {0xac8, 0x3fe00000}, - {0xee8, 0x3fe03fe0}, - {0xb09, 0x3ff00000}, - {0xf29, 0x3ff03ff0}, - {0xb4a, 0x3ff80000}, - {0xf6a, 0x3ff83ff8}, - {0xb8b, 0x3ffc0000}, - {0xfab, 0x3ffc3ffc}, - {0xbcc, 0x3ffe0000}, - {0xfec, 0x3ffe3ffe}, - {0xc0d, 0x3fff0000}, - {0xc2d, 0x3fff3fff}, - {0xc4e, 0x3fff8000}, - {0xc8f, 0x3fffc000}, - {0xcd0, 0x3fffe000}, - {0xd11, 0x3ffff000}, - {0xd52, 0x3ffff800}, - {0xd93, 0x3ffffc00}, - {0xdd4, 0x3ffffe00}, - {0xe15, 0x3fffff00}, - {0xe56, 0x3fffff80}, - {0xe97, 0x3fffffc0}, - {0xed8, 0x3fffffe0}, - {0xf19, 0x3ffffff0}, - {0xf5a, 0x3ffffff8}, - {0xf9b, 0x3ffffffc}, - {0xfdc, 0x3ffffffe}, - {0x81d, 0x3fffffff}, - {0x880, 0x40000000}, - {0xca0, 0x40004000}, - {0xeb0, 0x40404040}, - {0xfb8, 0x44444444}, - {0xfbc, 0x55555555}, - {0x8c1, 0x60000000}, - {0xce1, 0x60006000}, - {0xef1, 0x60606060}, - {0xff9, 0x66666666}, - {0x902, 0x70000000}, - {0xd22, 0x70007000}, - {0xf32, 0x70707070}, - {0xf3a, 0x77777777}, - {0x943, 0x78000000}, - {0xd63, 0x78007800}, - {0xf73, 0x78787878}, - {0x984, 0x7c000000}, - {0xda4, 0x7c007c00}, - {0xfb4, 0x7c7c7c7c}, - {0x9c5, 0x7e000000}, - {0xde5, 0x7e007e00}, - {0xff5, 0x7e7e7e7e}, - {0xa06, 0x7f000000}, - {0xe26, 0x7f007f00}, - {0xe36, 0x7f7f7f7f}, - {0xa47, 0x7f800000}, - {0xe67, 0x7f807f80}, - {0xa88, 0x7fc00000}, - {0xea8, 0x7fc07fc0}, - {0xac9, 0x7fe00000}, - {0xee9, 0x7fe07fe0}, - {0xb0a, 0x7ff00000}, - {0xf2a, 0x7ff07ff0}, - {0xb4b, 0x7ff80000}, - {0xf6b, 0x7ff87ff8}, - {0xb8c, 0x7ffc0000}, - {0xfac, 0x7ffc7ffc}, - {0xbcd, 0x7ffe0000}, - {0xfed, 0x7ffe7ffe}, - {0xc0e, 0x7fff0000}, - {0xc2e, 0x7fff7fff}, - {0xc4f, 0x7fff8000}, - {0xc90, 0x7fffc000}, - {0xcd1, 0x7fffe000}, - {0xd12, 0x7ffff000}, - {0xd53, 0x7ffff800}, - {0xd94, 0x7ffffc00}, - {0xdd5, 0x7ffffe00}, - {0xe16, 0x7fffff00}, - {0xe57, 0x7fffff80}, - {0xe98, 0x7fffffc0}, - {0xed9, 0x7fffffe0}, - {0xf1a, 0x7ffffff0}, - {0xf5b, 0x7ffffff8}, - {0xf9c, 0x7ffffffc}, - {0xfdd, 0x7ffffffe}, - {0x81e, 0x7fffffff}, - {0x840, 0x80000000}, - {0x841, 0x80000001}, - {0x842, 0x80000003}, - {0x843, 0x80000007}, - {0x844, 0x8000000f}, - {0x845, 0x8000001f}, - {0x846, 0x8000003f}, - {0x847, 0x8000007f}, - {0x848, 0x800000ff}, - {0x849, 0x800001ff}, - {0x84a, 0x800003ff}, - {0x84b, 0x800007ff}, - {0x84c, 0x80000fff}, - {0x84d, 0x80001fff}, - {0x84e, 0x80003fff}, - {0x84f, 0x80007fff}, - {0xc60, 0x80008000}, - {0x850, 0x8000ffff}, - {0xc61, 0x80018001}, - {0x851, 0x8001ffff}, - {0xc62, 0x80038003}, - {0x852, 0x8003ffff}, - {0xc63, 0x80078007}, - {0x853, 0x8007ffff}, - {0xc64, 0x800f800f}, - {0x854, 0x800fffff}, - {0xc65, 0x801f801f}, - {0x855, 0x801fffff}, - {0xc66, 0x803f803f}, - {0x856, 0x803fffff}, - {0xc67, 0x807f807f}, - {0x857, 0x807fffff}, - {0xe70, 0x80808080}, - {0xc68, 0x80ff80ff}, - {0x858, 0x80ffffff}, - {0xe71, 0x81818181}, - {0xc69, 0x81ff81ff}, - {0x859, 0x81ffffff}, - {0xe72, 0x83838383}, - {0xc6a, 0x83ff83ff}, - {0x85a, 0x83ffffff}, - {0xe73, 0x87878787}, - {0xc6b, 0x87ff87ff}, - {0x85b, 0x87ffffff}, - {0xf78, 0x88888888}, - {0xe74, 0x8f8f8f8f}, - {0xc6c, 0x8fff8fff}, - {0x85c, 0x8fffffff}, - {0xf79, 0x99999999}, - {0xe75, 0x9f9f9f9f}, - {0xc6d, 0x9fff9fff}, - {0x85d, 0x9fffffff}, - {0xffc, 0xaaaaaaaa}, - {0xf7a, 0xbbbbbbbb}, - {0xe76, 0xbfbfbfbf}, - {0xc6e, 0xbfffbfff}, - {0x85e, 0xbfffffff}, - {0x881, 0xc0000000}, - {0x882, 0xc0000001}, - {0x883, 0xc0000003}, - {0x884, 0xc0000007}, - {0x885, 0xc000000f}, - {0x886, 0xc000001f}, - {0x887, 0xc000003f}, - {0x888, 0xc000007f}, - {0x889, 0xc00000ff}, - {0x88a, 0xc00001ff}, - {0x88b, 0xc00003ff}, - {0x88c, 0xc00007ff}, - {0x88d, 0xc0000fff}, - {0x88e, 0xc0001fff}, - {0x88f, 0xc0003fff}, - {0x890, 0xc0007fff}, - {0xca1, 0xc000c000}, - {0x891, 0xc000ffff}, - {0xca2, 0xc001c001}, - {0x892, 0xc001ffff}, - {0xca3, 0xc003c003}, - {0x893, 0xc003ffff}, - {0xca4, 0xc007c007}, - {0x894, 0xc007ffff}, - {0xca5, 0xc00fc00f}, - {0x895, 0xc00fffff}, - {0xca6, 0xc01fc01f}, - {0x896, 0xc01fffff}, - {0xca7, 0xc03fc03f}, - {0x897, 0xc03fffff}, - {0xca8, 0xc07fc07f}, - {0x898, 0xc07fffff}, - {0xeb1, 0xc0c0c0c0}, - {0xca9, 0xc0ffc0ff}, - {0x899, 0xc0ffffff}, - {0xeb2, 0xc1c1c1c1}, - {0xcaa, 0xc1ffc1ff}, - {0x89a, 0xc1ffffff}, - {0xeb3, 0xc3c3c3c3}, - {0xcab, 0xc3ffc3ff}, - {0x89b, 0xc3ffffff}, - {0xeb4, 0xc7c7c7c7}, - {0xcac, 0xc7ffc7ff}, - {0x89c, 0xc7ffffff}, - {0xfb9, 0xcccccccc}, - {0xeb5, 0xcfcfcfcf}, - {0xcad, 0xcfffcfff}, - {0x89d, 0xcfffffff}, - {0xfba, 0xdddddddd}, - {0xeb6, 0xdfdfdfdf}, - {0xcae, 0xdfffdfff}, - {0x89e, 0xdfffffff}, - {0x8c2, 0xe0000000}, - {0x8c3, 0xe0000001}, - {0x8c4, 0xe0000003}, - {0x8c5, 0xe0000007}, - {0x8c6, 0xe000000f}, - {0x8c7, 0xe000001f}, - {0x8c8, 0xe000003f}, - {0x8c9, 0xe000007f}, - {0x8ca, 0xe00000ff}, - {0x8cb, 0xe00001ff}, - {0x8cc, 0xe00003ff}, - {0x8cd, 0xe00007ff}, - {0x8ce, 0xe0000fff}, - {0x8cf, 0xe0001fff}, - {0x8d0, 0xe0003fff}, - {0x8d1, 0xe0007fff}, - {0xce2, 0xe000e000}, - {0x8d2, 0xe000ffff}, - {0xce3, 0xe001e001}, - {0x8d3, 0xe001ffff}, - {0xce4, 0xe003e003}, - {0x8d4, 0xe003ffff}, - {0xce5, 0xe007e007}, - {0x8d5, 0xe007ffff}, - {0xce6, 0xe00fe00f}, - {0x8d6, 0xe00fffff}, - {0xce7, 0xe01fe01f}, - {0x8d7, 0xe01fffff}, - {0xce8, 0xe03fe03f}, - {0x8d8, 0xe03fffff}, - {0xce9, 0xe07fe07f}, - {0x8d9, 0xe07fffff}, - {0xef2, 0xe0e0e0e0}, - {0xcea, 0xe0ffe0ff}, - {0x8da, 0xe0ffffff}, - {0xef3, 0xe1e1e1e1}, - {0xceb, 0xe1ffe1ff}, - {0x8db, 0xe1ffffff}, - {0xef4, 0xe3e3e3e3}, - {0xcec, 0xe3ffe3ff}, - {0x8dc, 0xe3ffffff}, - {0xef5, 0xe7e7e7e7}, - {0xced, 0xe7ffe7ff}, - {0x8dd, 0xe7ffffff}, - {0xffa, 0xeeeeeeee}, - {0xef6, 0xefefefef}, - {0xcee, 0xefffefff}, - {0x8de, 0xefffffff}, - {0x903, 0xf0000000}, - {0x904, 0xf0000001}, - {0x905, 0xf0000003}, - {0x906, 0xf0000007}, - {0x907, 0xf000000f}, - {0x908, 0xf000001f}, - {0x909, 0xf000003f}, - {0x90a, 0xf000007f}, - {0x90b, 0xf00000ff}, - {0x90c, 0xf00001ff}, - {0x90d, 0xf00003ff}, - {0x90e, 0xf00007ff}, - {0x90f, 0xf0000fff}, - {0x910, 0xf0001fff}, - {0x911, 0xf0003fff}, - {0x912, 0xf0007fff}, - {0xd23, 0xf000f000}, - {0x913, 0xf000ffff}, - {0xd24, 0xf001f001}, - {0x914, 0xf001ffff}, - {0xd25, 0xf003f003}, - {0x915, 0xf003ffff}, - {0xd26, 0xf007f007}, - {0x916, 0xf007ffff}, - {0xd27, 0xf00ff00f}, - {0x917, 0xf00fffff}, - {0xd28, 0xf01ff01f}, - {0x918, 0xf01fffff}, - {0xd29, 0xf03ff03f}, - {0x919, 0xf03fffff}, - {0xd2a, 0xf07ff07f}, - {0x91a, 0xf07fffff}, - {0xf33, 0xf0f0f0f0}, - {0xd2b, 0xf0fff0ff}, - {0x91b, 0xf0ffffff}, - {0xf34, 0xf1f1f1f1}, - {0xd2c, 0xf1fff1ff}, - {0x91c, 0xf1ffffff}, - {0xf35, 0xf3f3f3f3}, - {0xd2d, 0xf3fff3ff}, - {0x91d, 0xf3ffffff}, - {0xf36, 0xf7f7f7f7}, - {0xd2e, 0xf7fff7ff}, - {0x91e, 0xf7ffffff}, - {0x944, 0xf8000000}, - {0x945, 0xf8000001}, - {0x946, 0xf8000003}, - {0x947, 0xf8000007}, - {0x948, 0xf800000f}, - {0x949, 0xf800001f}, - {0x94a, 0xf800003f}, - {0x94b, 0xf800007f}, - {0x94c, 0xf80000ff}, - {0x94d, 0xf80001ff}, - {0x94e, 0xf80003ff}, - {0x94f, 0xf80007ff}, - {0x950, 0xf8000fff}, - {0x951, 0xf8001fff}, - {0x952, 0xf8003fff}, - {0x953, 0xf8007fff}, - {0xd64, 0xf800f800}, - {0x954, 0xf800ffff}, - {0xd65, 0xf801f801}, - {0x955, 0xf801ffff}, - {0xd66, 0xf803f803}, - {0x956, 0xf803ffff}, - {0xd67, 0xf807f807}, - {0x957, 0xf807ffff}, - {0xd68, 0xf80ff80f}, - {0x958, 0xf80fffff}, - {0xd69, 0xf81ff81f}, - {0x959, 0xf81fffff}, - {0xd6a, 0xf83ff83f}, - {0x95a, 0xf83fffff}, - {0xd6b, 0xf87ff87f}, - {0x95b, 0xf87fffff}, - {0xf74, 0xf8f8f8f8}, - {0xd6c, 0xf8fff8ff}, - {0x95c, 0xf8ffffff}, - {0xf75, 0xf9f9f9f9}, - {0xd6d, 0xf9fff9ff}, - {0x95d, 0xf9ffffff}, - {0xf76, 0xfbfbfbfb}, - {0xd6e, 0xfbfffbff}, - {0x95e, 0xfbffffff}, - {0x985, 0xfc000000}, - {0x986, 0xfc000001}, - {0x987, 0xfc000003}, - {0x988, 0xfc000007}, - {0x989, 0xfc00000f}, - {0x98a, 0xfc00001f}, - {0x98b, 0xfc00003f}, - {0x98c, 0xfc00007f}, - {0x98d, 0xfc0000ff}, - {0x98e, 0xfc0001ff}, - {0x98f, 0xfc0003ff}, - {0x990, 0xfc0007ff}, - {0x991, 0xfc000fff}, - {0x992, 0xfc001fff}, - {0x993, 0xfc003fff}, - {0x994, 0xfc007fff}, - {0xda5, 0xfc00fc00}, - {0x995, 0xfc00ffff}, - {0xda6, 0xfc01fc01}, - {0x996, 0xfc01ffff}, - {0xda7, 0xfc03fc03}, - {0x997, 0xfc03ffff}, - {0xda8, 0xfc07fc07}, - {0x998, 0xfc07ffff}, - {0xda9, 0xfc0ffc0f}, - {0x999, 0xfc0fffff}, - {0xdaa, 0xfc1ffc1f}, - {0x99a, 0xfc1fffff}, - {0xdab, 0xfc3ffc3f}, - {0x99b, 0xfc3fffff}, - {0xdac, 0xfc7ffc7f}, - {0x99c, 0xfc7fffff}, - {0xfb5, 0xfcfcfcfc}, - {0xdad, 0xfcfffcff}, - {0x99d, 0xfcffffff}, - {0xfb6, 0xfdfdfdfd}, - {0xdae, 0xfdfffdff}, - {0x99e, 0xfdffffff}, - {0x9c6, 0xfe000000}, - {0x9c7, 0xfe000001}, - {0x9c8, 0xfe000003}, - {0x9c9, 0xfe000007}, - {0x9ca, 0xfe00000f}, - {0x9cb, 0xfe00001f}, - {0x9cc, 0xfe00003f}, - {0x9cd, 0xfe00007f}, - {0x9ce, 0xfe0000ff}, - {0x9cf, 0xfe0001ff}, - {0x9d0, 0xfe0003ff}, - {0x9d1, 0xfe0007ff}, - {0x9d2, 0xfe000fff}, - {0x9d3, 0xfe001fff}, - {0x9d4, 0xfe003fff}, - {0x9d5, 0xfe007fff}, - {0xde6, 0xfe00fe00}, - {0x9d6, 0xfe00ffff}, - {0xde7, 0xfe01fe01}, - {0x9d7, 0xfe01ffff}, - {0xde8, 0xfe03fe03}, - {0x9d8, 0xfe03ffff}, - {0xde9, 0xfe07fe07}, - {0x9d9, 0xfe07ffff}, - {0xdea, 0xfe0ffe0f}, - {0x9da, 0xfe0fffff}, - {0xdeb, 0xfe1ffe1f}, - {0x9db, 0xfe1fffff}, - {0xdec, 0xfe3ffe3f}, - {0x9dc, 0xfe3fffff}, - {0xded, 0xfe7ffe7f}, - {0x9dd, 0xfe7fffff}, - {0xff6, 0xfefefefe}, - {0xdee, 0xfefffeff}, - {0x9de, 0xfeffffff}, - {0xa07, 0xff000000}, - {0xa08, 0xff000001}, - {0xa09, 0xff000003}, - {0xa0a, 0xff000007}, - {0xa0b, 0xff00000f}, - {0xa0c, 0xff00001f}, - {0xa0d, 0xff00003f}, - {0xa0e, 0xff00007f}, - {0xa0f, 0xff0000ff}, - {0xa10, 0xff0001ff}, - {0xa11, 0xff0003ff}, - {0xa12, 0xff0007ff}, - {0xa13, 0xff000fff}, - {0xa14, 0xff001fff}, - {0xa15, 0xff003fff}, - {0xa16, 0xff007fff}, - {0xe27, 0xff00ff00}, - {0xa17, 0xff00ffff}, - {0xe28, 0xff01ff01}, - {0xa18, 0xff01ffff}, - {0xe29, 0xff03ff03}, - {0xa19, 0xff03ffff}, - {0xe2a, 0xff07ff07}, - {0xa1a, 0xff07ffff}, - {0xe2b, 0xff0fff0f}, - {0xa1b, 0xff0fffff}, - {0xe2c, 0xff1fff1f}, - {0xa1c, 0xff1fffff}, - {0xe2d, 0xff3fff3f}, - {0xa1d, 0xff3fffff}, - {0xe2e, 0xff7fff7f}, - {0xa1e, 0xff7fffff}, - {0xa48, 0xff800000}, - {0xa49, 0xff800001}, - {0xa4a, 0xff800003}, - {0xa4b, 0xff800007}, - {0xa4c, 0xff80000f}, - {0xa4d, 0xff80001f}, - {0xa4e, 0xff80003f}, - {0xa4f, 0xff80007f}, - {0xa50, 0xff8000ff}, - {0xa51, 0xff8001ff}, - {0xa52, 0xff8003ff}, - {0xa53, 0xff8007ff}, - {0xa54, 0xff800fff}, - {0xa55, 0xff801fff}, - {0xa56, 0xff803fff}, - {0xa57, 0xff807fff}, - {0xe68, 0xff80ff80}, - {0xa58, 0xff80ffff}, - {0xe69, 0xff81ff81}, - {0xa59, 0xff81ffff}, - {0xe6a, 0xff83ff83}, - {0xa5a, 0xff83ffff}, - {0xe6b, 0xff87ff87}, - {0xa5b, 0xff87ffff}, - {0xe6c, 0xff8fff8f}, - {0xa5c, 0xff8fffff}, - {0xe6d, 0xff9fff9f}, - {0xa5d, 0xff9fffff}, - {0xe6e, 0xffbfffbf}, - {0xa5e, 0xffbfffff}, - {0xa89, 0xffc00000}, - {0xa8a, 0xffc00001}, - {0xa8b, 0xffc00003}, - {0xa8c, 0xffc00007}, - {0xa8d, 0xffc0000f}, - {0xa8e, 0xffc0001f}, - {0xa8f, 0xffc0003f}, - {0xa90, 0xffc0007f}, - {0xa91, 0xffc000ff}, - {0xa92, 0xffc001ff}, - {0xa93, 0xffc003ff}, - {0xa94, 0xffc007ff}, - {0xa95, 0xffc00fff}, - {0xa96, 0xffc01fff}, - {0xa97, 0xffc03fff}, - {0xa98, 0xffc07fff}, - {0xea9, 0xffc0ffc0}, - {0xa99, 0xffc0ffff}, - {0xeaa, 0xffc1ffc1}, - {0xa9a, 0xffc1ffff}, - {0xeab, 0xffc3ffc3}, - {0xa9b, 0xffc3ffff}, - {0xeac, 0xffc7ffc7}, - {0xa9c, 0xffc7ffff}, - {0xead, 0xffcfffcf}, - {0xa9d, 0xffcfffff}, - {0xeae, 0xffdfffdf}, - {0xa9e, 0xffdfffff}, - {0xaca, 0xffe00000}, - {0xacb, 0xffe00001}, - {0xacc, 0xffe00003}, - {0xacd, 0xffe00007}, - {0xace, 0xffe0000f}, - {0xacf, 0xffe0001f}, - {0xad0, 0xffe0003f}, - {0xad1, 0xffe0007f}, - {0xad2, 0xffe000ff}, - {0xad3, 0xffe001ff}, - {0xad4, 0xffe003ff}, - {0xad5, 0xffe007ff}, - {0xad6, 0xffe00fff}, - {0xad7, 0xffe01fff}, - {0xad8, 0xffe03fff}, - {0xad9, 0xffe07fff}, - {0xeea, 0xffe0ffe0}, - {0xada, 0xffe0ffff}, - {0xeeb, 0xffe1ffe1}, - {0xadb, 0xffe1ffff}, - {0xeec, 0xffe3ffe3}, - {0xadc, 0xffe3ffff}, - {0xeed, 0xffe7ffe7}, - {0xadd, 0xffe7ffff}, - {0xeee, 0xffefffef}, - {0xade, 0xffefffff}, - {0xb0b, 0xfff00000}, - {0xb0c, 0xfff00001}, - {0xb0d, 0xfff00003}, - {0xb0e, 0xfff00007}, - {0xb0f, 0xfff0000f}, - {0xb10, 0xfff0001f}, - {0xb11, 0xfff0003f}, - {0xb12, 0xfff0007f}, - {0xb13, 0xfff000ff}, - {0xb14, 0xfff001ff}, - {0xb15, 0xfff003ff}, - {0xb16, 0xfff007ff}, - {0xb17, 0xfff00fff}, - {0xb18, 0xfff01fff}, - {0xb19, 0xfff03fff}, - {0xb1a, 0xfff07fff}, - {0xf2b, 0xfff0fff0}, - {0xb1b, 0xfff0ffff}, - {0xf2c, 0xfff1fff1}, - {0xb1c, 0xfff1ffff}, - {0xf2d, 0xfff3fff3}, - {0xb1d, 0xfff3ffff}, - {0xf2e, 0xfff7fff7}, - {0xb1e, 0xfff7ffff}, - {0xb4c, 0xfff80000}, - {0xb4d, 0xfff80001}, - {0xb4e, 0xfff80003}, - {0xb4f, 0xfff80007}, - {0xb50, 0xfff8000f}, - {0xb51, 0xfff8001f}, - {0xb52, 0xfff8003f}, - {0xb53, 0xfff8007f}, - {0xb54, 0xfff800ff}, - {0xb55, 0xfff801ff}, - {0xb56, 0xfff803ff}, - {0xb57, 0xfff807ff}, - {0xb58, 0xfff80fff}, - {0xb59, 0xfff81fff}, - {0xb5a, 0xfff83fff}, - {0xb5b, 0xfff87fff}, - {0xf6c, 0xfff8fff8}, - {0xb5c, 0xfff8ffff}, - {0xf6d, 0xfff9fff9}, - {0xb5d, 0xfff9ffff}, - {0xf6e, 0xfffbfffb}, - {0xb5e, 0xfffbffff}, - {0xb8d, 0xfffc0000}, - {0xb8e, 0xfffc0001}, - {0xb8f, 0xfffc0003}, - {0xb90, 0xfffc0007}, - {0xb91, 0xfffc000f}, - {0xb92, 0xfffc001f}, - {0xb93, 0xfffc003f}, - {0xb94, 0xfffc007f}, - {0xb95, 0xfffc00ff}, - {0xb96, 0xfffc01ff}, - {0xb97, 0xfffc03ff}, - {0xb98, 0xfffc07ff}, - {0xb99, 0xfffc0fff}, - {0xb9a, 0xfffc1fff}, - {0xb9b, 0xfffc3fff}, - {0xb9c, 0xfffc7fff}, - {0xfad, 0xfffcfffc}, - {0xb9d, 0xfffcffff}, - {0xfae, 0xfffdfffd}, - {0xb9e, 0xfffdffff}, - {0xbce, 0xfffe0000}, - {0xbcf, 0xfffe0001}, - {0xbd0, 0xfffe0003}, - {0xbd1, 0xfffe0007}, - {0xbd2, 0xfffe000f}, - {0xbd3, 0xfffe001f}, - {0xbd4, 0xfffe003f}, - {0xbd5, 0xfffe007f}, - {0xbd6, 0xfffe00ff}, - {0xbd7, 0xfffe01ff}, - {0xbd8, 0xfffe03ff}, - {0xbd9, 0xfffe07ff}, - {0xbda, 0xfffe0fff}, - {0xbdb, 0xfffe1fff}, - {0xbdc, 0xfffe3fff}, - {0xbdd, 0xfffe7fff}, - {0xfee, 0xfffefffe}, - {0xbde, 0xfffeffff}, - {0xc0f, 0xffff0000}, - {0xc10, 0xffff0001}, - {0xc11, 0xffff0003}, - {0xc12, 0xffff0007}, - {0xc13, 0xffff000f}, - {0xc14, 0xffff001f}, - {0xc15, 0xffff003f}, - {0xc16, 0xffff007f}, - {0xc17, 0xffff00ff}, - {0xc18, 0xffff01ff}, - {0xc19, 0xffff03ff}, - {0xc1a, 0xffff07ff}, - {0xc1b, 0xffff0fff}, - {0xc1c, 0xffff1fff}, - {0xc1d, 0xffff3fff}, - {0xc1e, 0xffff7fff}, - {0xc50, 0xffff8000}, - {0xc51, 0xffff8001}, - {0xc52, 0xffff8003}, - {0xc53, 0xffff8007}, - {0xc54, 0xffff800f}, - {0xc55, 0xffff801f}, - {0xc56, 0xffff803f}, - {0xc57, 0xffff807f}, - {0xc58, 0xffff80ff}, - {0xc59, 0xffff81ff}, - {0xc5a, 0xffff83ff}, - {0xc5b, 0xffff87ff}, - {0xc5c, 0xffff8fff}, - {0xc5d, 0xffff9fff}, - {0xc5e, 0xffffbfff}, - {0xc91, 0xffffc000}, - {0xc92, 0xffffc001}, - {0xc93, 0xffffc003}, - {0xc94, 0xffffc007}, - {0xc95, 0xffffc00f}, - {0xc96, 0xffffc01f}, - {0xc97, 0xffffc03f}, - {0xc98, 0xffffc07f}, - {0xc99, 0xffffc0ff}, - {0xc9a, 0xffffc1ff}, - {0xc9b, 0xffffc3ff}, - {0xc9c, 0xffffc7ff}, - {0xc9d, 0xffffcfff}, - {0xc9e, 0xffffdfff}, - {0xcd2, 0xffffe000}, - {0xcd3, 0xffffe001}, - {0xcd4, 0xffffe003}, - {0xcd5, 0xffffe007}, - {0xcd6, 0xffffe00f}, - {0xcd7, 0xffffe01f}, - {0xcd8, 0xffffe03f}, - {0xcd9, 0xffffe07f}, - {0xcda, 0xffffe0ff}, - {0xcdb, 0xffffe1ff}, - {0xcdc, 0xffffe3ff}, - {0xcdd, 0xffffe7ff}, - {0xcde, 0xffffefff}, - {0xd13, 0xfffff000}, - {0xd14, 0xfffff001}, - {0xd15, 0xfffff003}, - {0xd16, 0xfffff007}, - {0xd17, 0xfffff00f}, - {0xd18, 0xfffff01f}, - {0xd19, 0xfffff03f}, - {0xd1a, 0xfffff07f}, - {0xd1b, 0xfffff0ff}, - {0xd1c, 0xfffff1ff}, - {0xd1d, 0xfffff3ff}, - {0xd1e, 0xfffff7ff}, - {0xd54, 0xfffff800}, - {0xd55, 0xfffff801}, - {0xd56, 0xfffff803}, - {0xd57, 0xfffff807}, - {0xd58, 0xfffff80f}, - {0xd59, 0xfffff81f}, - {0xd5a, 0xfffff83f}, - {0xd5b, 0xfffff87f}, - {0xd5c, 0xfffff8ff}, - {0xd5d, 0xfffff9ff}, - {0xd5e, 0xfffffbff}, - {0xd95, 0xfffffc00}, - {0xd96, 0xfffffc01}, - {0xd97, 0xfffffc03}, - {0xd98, 0xfffffc07}, - {0xd99, 0xfffffc0f}, - {0xd9a, 0xfffffc1f}, - {0xd9b, 0xfffffc3f}, - {0xd9c, 0xfffffc7f}, - {0xd9d, 0xfffffcff}, - {0xd9e, 0xfffffdff}, - {0xdd6, 0xfffffe00}, - {0xdd7, 0xfffffe01}, - {0xdd8, 0xfffffe03}, - {0xdd9, 0xfffffe07}, - {0xdda, 0xfffffe0f}, - {0xddb, 0xfffffe1f}, - {0xddc, 0xfffffe3f}, - {0xddd, 0xfffffe7f}, - {0xdde, 0xfffffeff}, - {0xe17, 0xffffff00}, - {0xe18, 0xffffff01}, - {0xe19, 0xffffff03}, - {0xe1a, 0xffffff07}, - {0xe1b, 0xffffff0f}, - {0xe1c, 0xffffff1f}, - {0xe1d, 0xffffff3f}, - {0xe1e, 0xffffff7f}, - {0xe58, 0xffffff80}, - {0xe59, 0xffffff81}, - {0xe5a, 0xffffff83}, - {0xe5b, 0xffffff87}, - {0xe5c, 0xffffff8f}, - {0xe5d, 0xffffff9f}, - {0xe5e, 0xffffffbf}, - {0xe99, 0xffffffc0}, - {0xe9a, 0xffffffc1}, - {0xe9b, 0xffffffc3}, - {0xe9c, 0xffffffc7}, - {0xe9d, 0xffffffcf}, - {0xe9e, 0xffffffdf}, - {0xeda, 0xffffffe0}, - {0xedb, 0xffffffe1}, - {0xedc, 0xffffffe3}, - {0xedd, 0xffffffe7}, - {0xede, 0xffffffef}, - {0xf1b, 0xfffffff0}, - {0xf1c, 0xfffffff1}, - {0xf1d, 0xfffffff3}, - {0xf1e, 0xfffffff7}, - {0xf5c, 0xfffffff8}, - {0xf5d, 0xfffffff9}, - {0xf5e, 0xfffffffb}, - {0xf9d, 0xfffffffc}, - {0xf9e, 0xfffffffd}, - {0xfde, 0xfffffffe}, +static uint32_t imm_table[][2] = { + {0x800, 0x00000001}, + { 0xfc0, 0x00000002}, + { 0x801, 0x00000003}, + { 0xf80, 0x00000004}, + { 0xfc1, 0x00000006}, + { 0x802, 0x00000007}, + { 0xf40, 0x00000008}, + { 0xf81, 0x0000000c}, + { 0xfc2, 0x0000000e}, + { 0x803, 0x0000000f}, + { 0xf00, 0x00000010}, + { 0xf41, 0x00000018}, + { 0xf82, 0x0000001c}, + { 0xfc3, 0x0000001e}, + { 0x804, 0x0000001f}, + { 0xec0, 0x00000020}, + { 0xf01, 0x00000030}, + { 0xf42, 0x00000038}, + { 0xf83, 0x0000003c}, + { 0xfc4, 0x0000003e}, + { 0x805, 0x0000003f}, + { 0xe80, 0x00000040}, + { 0xec1, 0x00000060}, + { 0xf02, 0x00000070}, + { 0xf43, 0x00000078}, + { 0xf84, 0x0000007c}, + { 0xfc5, 0x0000007e}, + { 0x806, 0x0000007f}, + { 0xe40, 0x00000080}, + { 0xe81, 0x000000c0}, + { 0xec2, 0x000000e0}, + { 0xf03, 0x000000f0}, + { 0xf44, 0x000000f8}, + { 0xf85, 0x000000fc}, + { 0xfc6, 0x000000fe}, + { 0x807, 0x000000ff}, + { 0xe00, 0x00000100}, + { 0xe41, 0x00000180}, + { 0xe82, 0x000001c0}, + { 0xec3, 0x000001e0}, + { 0xf04, 0x000001f0}, + { 0xf45, 0x000001f8}, + { 0xf86, 0x000001fc}, + { 0xfc7, 0x000001fe}, + { 0x808, 0x000001ff}, + { 0xdc0, 0x00000200}, + { 0xe01, 0x00000300}, + { 0xe42, 0x00000380}, + { 0xe83, 0x000003c0}, + { 0xec4, 0x000003e0}, + { 0xf05, 0x000003f0}, + { 0xf46, 0x000003f8}, + { 0xf87, 0x000003fc}, + { 0xfc8, 0x000003fe}, + { 0x809, 0x000003ff}, + { 0xd80, 0x00000400}, + { 0xdc1, 0x00000600}, + { 0xe02, 0x00000700}, + { 0xe43, 0x00000780}, + { 0xe84, 0x000007c0}, + { 0xec5, 0x000007e0}, + { 0xf06, 0x000007f0}, + { 0xf47, 0x000007f8}, + { 0xf88, 0x000007fc}, + { 0xfc9, 0x000007fe}, + { 0x80a, 0x000007ff}, + { 0xd40, 0x00000800}, + { 0xd81, 0x00000c00}, + { 0xdc2, 0x00000e00}, + { 0xe03, 0x00000f00}, + { 0xe44, 0x00000f80}, + { 0xe85, 0x00000fc0}, + { 0xec6, 0x00000fe0}, + { 0xf07, 0x00000ff0}, + { 0xf48, 0x00000ff8}, + { 0xf89, 0x00000ffc}, + { 0xfca, 0x00000ffe}, + { 0x80b, 0x00000fff}, + { 0xd00, 0x00001000}, + { 0xd41, 0x00001800}, + { 0xd82, 0x00001c00}, + { 0xdc3, 0x00001e00}, + { 0xe04, 0x00001f00}, + { 0xe45, 0x00001f80}, + { 0xe86, 0x00001fc0}, + { 0xec7, 0x00001fe0}, + { 0xf08, 0x00001ff0}, + { 0xf49, 0x00001ff8}, + { 0xf8a, 0x00001ffc}, + { 0xfcb, 0x00001ffe}, + { 0x80c, 0x00001fff}, + { 0xcc0, 0x00002000}, + { 0xd01, 0x00003000}, + { 0xd42, 0x00003800}, + { 0xd83, 0x00003c00}, + { 0xdc4, 0x00003e00}, + { 0xe05, 0x00003f00}, + { 0xe46, 0x00003f80}, + { 0xe87, 0x00003fc0}, + { 0xec8, 0x00003fe0}, + { 0xf09, 0x00003ff0}, + { 0xf4a, 0x00003ff8}, + { 0xf8b, 0x00003ffc}, + { 0xfcc, 0x00003ffe}, + { 0x80d, 0x00003fff}, + { 0xc80, 0x00004000}, + { 0xcc1, 0x00006000}, + { 0xd02, 0x00007000}, + { 0xd43, 0x00007800}, + { 0xd84, 0x00007c00}, + { 0xdc5, 0x00007e00}, + { 0xe06, 0x00007f00}, + { 0xe47, 0x00007f80}, + { 0xe88, 0x00007fc0}, + { 0xec9, 0x00007fe0}, + { 0xf0a, 0x00007ff0}, + { 0xf4b, 0x00007ff8}, + { 0xf8c, 0x00007ffc}, + { 0xfcd, 0x00007ffe}, + { 0x80e, 0x00007fff}, + { 0xc40, 0x00008000}, + { 0xc81, 0x0000c000}, + { 0xcc2, 0x0000e000}, + { 0xd03, 0x0000f000}, + { 0xd44, 0x0000f800}, + { 0xd85, 0x0000fc00}, + { 0xdc6, 0x0000fe00}, + { 0xe07, 0x0000ff00}, + { 0xe48, 0x0000ff80}, + { 0xe89, 0x0000ffc0}, + { 0xeca, 0x0000ffe0}, + { 0xf0b, 0x0000fff0}, + { 0xf4c, 0x0000fff8}, + { 0xf8d, 0x0000fffc}, + { 0xfce, 0x0000fffe}, + { 0x80f, 0x0000ffff}, + { 0xc00, 0x00010000}, + { 0xc20, 0x00010001}, + { 0xc41, 0x00018000}, + { 0xc82, 0x0001c000}, + { 0xcc3, 0x0001e000}, + { 0xd04, 0x0001f000}, + { 0xd45, 0x0001f800}, + { 0xd86, 0x0001fc00}, + { 0xdc7, 0x0001fe00}, + { 0xe08, 0x0001ff00}, + { 0xe49, 0x0001ff80}, + { 0xe8a, 0x0001ffc0}, + { 0xecb, 0x0001ffe0}, + { 0xf0c, 0x0001fff0}, + { 0xf4d, 0x0001fff8}, + { 0xf8e, 0x0001fffc}, + { 0xfcf, 0x0001fffe}, + { 0x810, 0x0001ffff}, + { 0xbc0, 0x00020000}, + { 0xfe0, 0x00020002}, + { 0xc01, 0x00030000}, + { 0xc21, 0x00030003}, + { 0xc42, 0x00038000}, + { 0xc83, 0x0003c000}, + { 0xcc4, 0x0003e000}, + { 0xd05, 0x0003f000}, + { 0xd46, 0x0003f800}, + { 0xd87, 0x0003fc00}, + { 0xdc8, 0x0003fe00}, + { 0xe09, 0x0003ff00}, + { 0xe4a, 0x0003ff80}, + { 0xe8b, 0x0003ffc0}, + { 0xecc, 0x0003ffe0}, + { 0xf0d, 0x0003fff0}, + { 0xf4e, 0x0003fff8}, + { 0xf8f, 0x0003fffc}, + { 0xfd0, 0x0003fffe}, + { 0x811, 0x0003ffff}, + { 0xb80, 0x00040000}, + { 0xfa0, 0x00040004}, + { 0xbc1, 0x00060000}, + { 0xfe1, 0x00060006}, + { 0xc02, 0x00070000}, + { 0xc22, 0x00070007}, + { 0xc43, 0x00078000}, + { 0xc84, 0x0007c000}, + { 0xcc5, 0x0007e000}, + { 0xd06, 0x0007f000}, + { 0xd47, 0x0007f800}, + { 0xd88, 0x0007fc00}, + { 0xdc9, 0x0007fe00}, + { 0xe0a, 0x0007ff00}, + { 0xe4b, 0x0007ff80}, + { 0xe8c, 0x0007ffc0}, + { 0xecd, 0x0007ffe0}, + { 0xf0e, 0x0007fff0}, + { 0xf4f, 0x0007fff8}, + { 0xf90, 0x0007fffc}, + { 0xfd1, 0x0007fffe}, + { 0x812, 0x0007ffff}, + { 0xb40, 0x00080000}, + { 0xf60, 0x00080008}, + { 0xb81, 0x000c0000}, + { 0xfa1, 0x000c000c}, + { 0xbc2, 0x000e0000}, + { 0xfe2, 0x000e000e}, + { 0xc03, 0x000f0000}, + { 0xc23, 0x000f000f}, + { 0xc44, 0x000f8000}, + { 0xc85, 0x000fc000}, + { 0xcc6, 0x000fe000}, + { 0xd07, 0x000ff000}, + { 0xd48, 0x000ff800}, + { 0xd89, 0x000ffc00}, + { 0xdca, 0x000ffe00}, + { 0xe0b, 0x000fff00}, + { 0xe4c, 0x000fff80}, + { 0xe8d, 0x000fffc0}, + { 0xece, 0x000fffe0}, + { 0xf0f, 0x000ffff0}, + { 0xf50, 0x000ffff8}, + { 0xf91, 0x000ffffc}, + { 0xfd2, 0x000ffffe}, + { 0x813, 0x000fffff}, + { 0xb00, 0x00100000}, + { 0xf20, 0x00100010}, + { 0xb41, 0x00180000}, + { 0xf61, 0x00180018}, + { 0xb82, 0x001c0000}, + { 0xfa2, 0x001c001c}, + { 0xbc3, 0x001e0000}, + { 0xfe3, 0x001e001e}, + { 0xc04, 0x001f0000}, + { 0xc24, 0x001f001f}, + { 0xc45, 0x001f8000}, + { 0xc86, 0x001fc000}, + { 0xcc7, 0x001fe000}, + { 0xd08, 0x001ff000}, + { 0xd49, 0x001ff800}, + { 0xd8a, 0x001ffc00}, + { 0xdcb, 0x001ffe00}, + { 0xe0c, 0x001fff00}, + { 0xe4d, 0x001fff80}, + { 0xe8e, 0x001fffc0}, + { 0xecf, 0x001fffe0}, + { 0xf10, 0x001ffff0}, + { 0xf51, 0x001ffff8}, + { 0xf92, 0x001ffffc}, + { 0xfd3, 0x001ffffe}, + { 0x814, 0x001fffff}, + { 0xac0, 0x00200000}, + { 0xee0, 0x00200020}, + { 0xb01, 0x00300000}, + { 0xf21, 0x00300030}, + { 0xb42, 0x00380000}, + { 0xf62, 0x00380038}, + { 0xb83, 0x003c0000}, + { 0xfa3, 0x003c003c}, + { 0xbc4, 0x003e0000}, + { 0xfe4, 0x003e003e}, + { 0xc05, 0x003f0000}, + { 0xc25, 0x003f003f}, + { 0xc46, 0x003f8000}, + { 0xc87, 0x003fc000}, + { 0xcc8, 0x003fe000}, + { 0xd09, 0x003ff000}, + { 0xd4a, 0x003ff800}, + { 0xd8b, 0x003ffc00}, + { 0xdcc, 0x003ffe00}, + { 0xe0d, 0x003fff00}, + { 0xe4e, 0x003fff80}, + { 0xe8f, 0x003fffc0}, + { 0xed0, 0x003fffe0}, + { 0xf11, 0x003ffff0}, + { 0xf52, 0x003ffff8}, + { 0xf93, 0x003ffffc}, + { 0xfd4, 0x003ffffe}, + { 0x815, 0x003fffff}, + { 0xa80, 0x00400000}, + { 0xea0, 0x00400040}, + { 0xac1, 0x00600000}, + { 0xee1, 0x00600060}, + { 0xb02, 0x00700000}, + { 0xf22, 0x00700070}, + { 0xb43, 0x00780000}, + { 0xf63, 0x00780078}, + { 0xb84, 0x007c0000}, + { 0xfa4, 0x007c007c}, + { 0xbc5, 0x007e0000}, + { 0xfe5, 0x007e007e}, + { 0xc06, 0x007f0000}, + { 0xc26, 0x007f007f}, + { 0xc47, 0x007f8000}, + { 0xc88, 0x007fc000}, + { 0xcc9, 0x007fe000}, + { 0xd0a, 0x007ff000}, + { 0xd4b, 0x007ff800}, + { 0xd8c, 0x007ffc00}, + { 0xdcd, 0x007ffe00}, + { 0xe0e, 0x007fff00}, + { 0xe4f, 0x007fff80}, + { 0xe90, 0x007fffc0}, + { 0xed1, 0x007fffe0}, + { 0xf12, 0x007ffff0}, + { 0xf53, 0x007ffff8}, + { 0xf94, 0x007ffffc}, + { 0xfd5, 0x007ffffe}, + { 0x816, 0x007fffff}, + { 0xa40, 0x00800000}, + { 0xe60, 0x00800080}, + { 0xa81, 0x00c00000}, + { 0xea1, 0x00c000c0}, + { 0xac2, 0x00e00000}, + { 0xee2, 0x00e000e0}, + { 0xb03, 0x00f00000}, + { 0xf23, 0x00f000f0}, + { 0xb44, 0x00f80000}, + { 0xf64, 0x00f800f8}, + { 0xb85, 0x00fc0000}, + { 0xfa5, 0x00fc00fc}, + { 0xbc6, 0x00fe0000}, + { 0xfe6, 0x00fe00fe}, + { 0xc07, 0x00ff0000}, + { 0xc27, 0x00ff00ff}, + { 0xc48, 0x00ff8000}, + { 0xc89, 0x00ffc000}, + { 0xcca, 0x00ffe000}, + { 0xd0b, 0x00fff000}, + { 0xd4c, 0x00fff800}, + { 0xd8d, 0x00fffc00}, + { 0xdce, 0x00fffe00}, + { 0xe0f, 0x00ffff00}, + { 0xe50, 0x00ffff80}, + { 0xe91, 0x00ffffc0}, + { 0xed2, 0x00ffffe0}, + { 0xf13, 0x00fffff0}, + { 0xf54, 0x00fffff8}, + { 0xf95, 0x00fffffc}, + { 0xfd6, 0x00fffffe}, + { 0x817, 0x00ffffff}, + { 0xa00, 0x01000000}, + { 0xe20, 0x01000100}, + { 0xe30, 0x01010101}, + { 0xa41, 0x01800000}, + { 0xe61, 0x01800180}, + { 0xa82, 0x01c00000}, + { 0xea2, 0x01c001c0}, + { 0xac3, 0x01e00000}, + { 0xee3, 0x01e001e0}, + { 0xb04, 0x01f00000}, + { 0xf24, 0x01f001f0}, + { 0xb45, 0x01f80000}, + { 0xf65, 0x01f801f8}, + { 0xb86, 0x01fc0000}, + { 0xfa6, 0x01fc01fc}, + { 0xbc7, 0x01fe0000}, + { 0xfe7, 0x01fe01fe}, + { 0xc08, 0x01ff0000}, + { 0xc28, 0x01ff01ff}, + { 0xc49, 0x01ff8000}, + { 0xc8a, 0x01ffc000}, + { 0xccb, 0x01ffe000}, + { 0xd0c, 0x01fff000}, + { 0xd4d, 0x01fff800}, + { 0xd8e, 0x01fffc00}, + { 0xdcf, 0x01fffe00}, + { 0xe10, 0x01ffff00}, + { 0xe51, 0x01ffff80}, + { 0xe92, 0x01ffffc0}, + { 0xed3, 0x01ffffe0}, + { 0xf14, 0x01fffff0}, + { 0xf55, 0x01fffff8}, + { 0xf96, 0x01fffffc}, + { 0xfd7, 0x01fffffe}, + { 0x818, 0x01ffffff}, + { 0x9c0, 0x02000000}, + { 0xde0, 0x02000200}, + { 0xff0, 0x02020202}, + { 0xa01, 0x03000000}, + { 0xe21, 0x03000300}, + { 0xe31, 0x03030303}, + { 0xa42, 0x03800000}, + { 0xe62, 0x03800380}, + { 0xa83, 0x03c00000}, + { 0xea3, 0x03c003c0}, + { 0xac4, 0x03e00000}, + { 0xee4, 0x03e003e0}, + { 0xb05, 0x03f00000}, + { 0xf25, 0x03f003f0}, + { 0xb46, 0x03f80000}, + { 0xf66, 0x03f803f8}, + { 0xb87, 0x03fc0000}, + { 0xfa7, 0x03fc03fc}, + { 0xbc8, 0x03fe0000}, + { 0xfe8, 0x03fe03fe}, + { 0xc09, 0x03ff0000}, + { 0xc29, 0x03ff03ff}, + { 0xc4a, 0x03ff8000}, + { 0xc8b, 0x03ffc000}, + { 0xccc, 0x03ffe000}, + { 0xd0d, 0x03fff000}, + { 0xd4e, 0x03fff800}, + { 0xd8f, 0x03fffc00}, + { 0xdd0, 0x03fffe00}, + { 0xe11, 0x03ffff00}, + { 0xe52, 0x03ffff80}, + { 0xe93, 0x03ffffc0}, + { 0xed4, 0x03ffffe0}, + { 0xf15, 0x03fffff0}, + { 0xf56, 0x03fffff8}, + { 0xf97, 0x03fffffc}, + { 0xfd8, 0x03fffffe}, + { 0x819, 0x03ffffff}, + { 0x980, 0x04000000}, + { 0xda0, 0x04000400}, + { 0xfb0, 0x04040404}, + { 0x9c1, 0x06000000}, + { 0xde1, 0x06000600}, + { 0xff1, 0x06060606}, + { 0xa02, 0x07000000}, + { 0xe22, 0x07000700}, + { 0xe32, 0x07070707}, + { 0xa43, 0x07800000}, + { 0xe63, 0x07800780}, + { 0xa84, 0x07c00000}, + { 0xea4, 0x07c007c0}, + { 0xac5, 0x07e00000}, + { 0xee5, 0x07e007e0}, + { 0xb06, 0x07f00000}, + { 0xf26, 0x07f007f0}, + { 0xb47, 0x07f80000}, + { 0xf67, 0x07f807f8}, + { 0xb88, 0x07fc0000}, + { 0xfa8, 0x07fc07fc}, + { 0xbc9, 0x07fe0000}, + { 0xfe9, 0x07fe07fe}, + { 0xc0a, 0x07ff0000}, + { 0xc2a, 0x07ff07ff}, + { 0xc4b, 0x07ff8000}, + { 0xc8c, 0x07ffc000}, + { 0xccd, 0x07ffe000}, + { 0xd0e, 0x07fff000}, + { 0xd4f, 0x07fff800}, + { 0xd90, 0x07fffc00}, + { 0xdd1, 0x07fffe00}, + { 0xe12, 0x07ffff00}, + { 0xe53, 0x07ffff80}, + { 0xe94, 0x07ffffc0}, + { 0xed5, 0x07ffffe0}, + { 0xf16, 0x07fffff0}, + { 0xf57, 0x07fffff8}, + { 0xf98, 0x07fffffc}, + { 0xfd9, 0x07fffffe}, + { 0x81a, 0x07ffffff}, + { 0x940, 0x08000000}, + { 0xd60, 0x08000800}, + { 0xf70, 0x08080808}, + { 0x981, 0x0c000000}, + { 0xda1, 0x0c000c00}, + { 0xfb1, 0x0c0c0c0c}, + { 0x9c2, 0x0e000000}, + { 0xde2, 0x0e000e00}, + { 0xff2, 0x0e0e0e0e}, + { 0xa03, 0x0f000000}, + { 0xe23, 0x0f000f00}, + { 0xe33, 0x0f0f0f0f}, + { 0xa44, 0x0f800000}, + { 0xe64, 0x0f800f80}, + { 0xa85, 0x0fc00000}, + { 0xea5, 0x0fc00fc0}, + { 0xac6, 0x0fe00000}, + { 0xee6, 0x0fe00fe0}, + { 0xb07, 0x0ff00000}, + { 0xf27, 0x0ff00ff0}, + { 0xb48, 0x0ff80000}, + { 0xf68, 0x0ff80ff8}, + { 0xb89, 0x0ffc0000}, + { 0xfa9, 0x0ffc0ffc}, + { 0xbca, 0x0ffe0000}, + { 0xfea, 0x0ffe0ffe}, + { 0xc0b, 0x0fff0000}, + { 0xc2b, 0x0fff0fff}, + { 0xc4c, 0x0fff8000}, + { 0xc8d, 0x0fffc000}, + { 0xcce, 0x0fffe000}, + { 0xd0f, 0x0ffff000}, + { 0xd50, 0x0ffff800}, + { 0xd91, 0x0ffffc00}, + { 0xdd2, 0x0ffffe00}, + { 0xe13, 0x0fffff00}, + { 0xe54, 0x0fffff80}, + { 0xe95, 0x0fffffc0}, + { 0xed6, 0x0fffffe0}, + { 0xf17, 0x0ffffff0}, + { 0xf58, 0x0ffffff8}, + { 0xf99, 0x0ffffffc}, + { 0xfda, 0x0ffffffe}, + { 0x81b, 0x0fffffff}, + { 0x900, 0x10000000}, + { 0xd20, 0x10001000}, + { 0xf30, 0x10101010}, + { 0xf38, 0x11111111}, + { 0x941, 0x18000000}, + { 0xd61, 0x18001800}, + { 0xf71, 0x18181818}, + { 0x982, 0x1c000000}, + { 0xda2, 0x1c001c00}, + { 0xfb2, 0x1c1c1c1c}, + { 0x9c3, 0x1e000000}, + { 0xde3, 0x1e001e00}, + { 0xff3, 0x1e1e1e1e}, + { 0xa04, 0x1f000000}, + { 0xe24, 0x1f001f00}, + { 0xe34, 0x1f1f1f1f}, + { 0xa45, 0x1f800000}, + { 0xe65, 0x1f801f80}, + { 0xa86, 0x1fc00000}, + { 0xea6, 0x1fc01fc0}, + { 0xac7, 0x1fe00000}, + { 0xee7, 0x1fe01fe0}, + { 0xb08, 0x1ff00000}, + { 0xf28, 0x1ff01ff0}, + { 0xb49, 0x1ff80000}, + { 0xf69, 0x1ff81ff8}, + { 0xb8a, 0x1ffc0000}, + { 0xfaa, 0x1ffc1ffc}, + { 0xbcb, 0x1ffe0000}, + { 0xfeb, 0x1ffe1ffe}, + { 0xc0c, 0x1fff0000}, + { 0xc2c, 0x1fff1fff}, + { 0xc4d, 0x1fff8000}, + { 0xc8e, 0x1fffc000}, + { 0xccf, 0x1fffe000}, + { 0xd10, 0x1ffff000}, + { 0xd51, 0x1ffff800}, + { 0xd92, 0x1ffffc00}, + { 0xdd3, 0x1ffffe00}, + { 0xe14, 0x1fffff00}, + { 0xe55, 0x1fffff80}, + { 0xe96, 0x1fffffc0}, + { 0xed7, 0x1fffffe0}, + { 0xf18, 0x1ffffff0}, + { 0xf59, 0x1ffffff8}, + { 0xf9a, 0x1ffffffc}, + { 0xfdb, 0x1ffffffe}, + { 0x81c, 0x1fffffff}, + { 0x8c0, 0x20000000}, + { 0xce0, 0x20002000}, + { 0xef0, 0x20202020}, + { 0xff8, 0x22222222}, + { 0x901, 0x30000000}, + { 0xd21, 0x30003000}, + { 0xf31, 0x30303030}, + { 0xf39, 0x33333333}, + { 0x942, 0x38000000}, + { 0xd62, 0x38003800}, + { 0xf72, 0x38383838}, + { 0x983, 0x3c000000}, + { 0xda3, 0x3c003c00}, + { 0xfb3, 0x3c3c3c3c}, + { 0x9c4, 0x3e000000}, + { 0xde4, 0x3e003e00}, + { 0xff4, 0x3e3e3e3e}, + { 0xa05, 0x3f000000}, + { 0xe25, 0x3f003f00}, + { 0xe35, 0x3f3f3f3f}, + { 0xa46, 0x3f800000}, + { 0xe66, 0x3f803f80}, + { 0xa87, 0x3fc00000}, + { 0xea7, 0x3fc03fc0}, + { 0xac8, 0x3fe00000}, + { 0xee8, 0x3fe03fe0}, + { 0xb09, 0x3ff00000}, + { 0xf29, 0x3ff03ff0}, + { 0xb4a, 0x3ff80000}, + { 0xf6a, 0x3ff83ff8}, + { 0xb8b, 0x3ffc0000}, + { 0xfab, 0x3ffc3ffc}, + { 0xbcc, 0x3ffe0000}, + { 0xfec, 0x3ffe3ffe}, + { 0xc0d, 0x3fff0000}, + { 0xc2d, 0x3fff3fff}, + { 0xc4e, 0x3fff8000}, + { 0xc8f, 0x3fffc000}, + { 0xcd0, 0x3fffe000}, + { 0xd11, 0x3ffff000}, + { 0xd52, 0x3ffff800}, + { 0xd93, 0x3ffffc00}, + { 0xdd4, 0x3ffffe00}, + { 0xe15, 0x3fffff00}, + { 0xe56, 0x3fffff80}, + { 0xe97, 0x3fffffc0}, + { 0xed8, 0x3fffffe0}, + { 0xf19, 0x3ffffff0}, + { 0xf5a, 0x3ffffff8}, + { 0xf9b, 0x3ffffffc}, + { 0xfdc, 0x3ffffffe}, + { 0x81d, 0x3fffffff}, + { 0x880, 0x40000000}, + { 0xca0, 0x40004000}, + { 0xeb0, 0x40404040}, + { 0xfb8, 0x44444444}, + { 0xfbc, 0x55555555}, + { 0x8c1, 0x60000000}, + { 0xce1, 0x60006000}, + { 0xef1, 0x60606060}, + { 0xff9, 0x66666666}, + { 0x902, 0x70000000}, + { 0xd22, 0x70007000}, + { 0xf32, 0x70707070}, + { 0xf3a, 0x77777777}, + { 0x943, 0x78000000}, + { 0xd63, 0x78007800}, + { 0xf73, 0x78787878}, + { 0x984, 0x7c000000}, + { 0xda4, 0x7c007c00}, + { 0xfb4, 0x7c7c7c7c}, + { 0x9c5, 0x7e000000}, + { 0xde5, 0x7e007e00}, + { 0xff5, 0x7e7e7e7e}, + { 0xa06, 0x7f000000}, + { 0xe26, 0x7f007f00}, + { 0xe36, 0x7f7f7f7f}, + { 0xa47, 0x7f800000}, + { 0xe67, 0x7f807f80}, + { 0xa88, 0x7fc00000}, + { 0xea8, 0x7fc07fc0}, + { 0xac9, 0x7fe00000}, + { 0xee9, 0x7fe07fe0}, + { 0xb0a, 0x7ff00000}, + { 0xf2a, 0x7ff07ff0}, + { 0xb4b, 0x7ff80000}, + { 0xf6b, 0x7ff87ff8}, + { 0xb8c, 0x7ffc0000}, + { 0xfac, 0x7ffc7ffc}, + { 0xbcd, 0x7ffe0000}, + { 0xfed, 0x7ffe7ffe}, + { 0xc0e, 0x7fff0000}, + { 0xc2e, 0x7fff7fff}, + { 0xc4f, 0x7fff8000}, + { 0xc90, 0x7fffc000}, + { 0xcd1, 0x7fffe000}, + { 0xd12, 0x7ffff000}, + { 0xd53, 0x7ffff800}, + { 0xd94, 0x7ffffc00}, + { 0xdd5, 0x7ffffe00}, + { 0xe16, 0x7fffff00}, + { 0xe57, 0x7fffff80}, + { 0xe98, 0x7fffffc0}, + { 0xed9, 0x7fffffe0}, + { 0xf1a, 0x7ffffff0}, + { 0xf5b, 0x7ffffff8}, + { 0xf9c, 0x7ffffffc}, + { 0xfdd, 0x7ffffffe}, + { 0x81e, 0x7fffffff}, + { 0x840, 0x80000000}, + { 0x841, 0x80000001}, + { 0x842, 0x80000003}, + { 0x843, 0x80000007}, + { 0x844, 0x8000000f}, + { 0x845, 0x8000001f}, + { 0x846, 0x8000003f}, + { 0x847, 0x8000007f}, + { 0x848, 0x800000ff}, + { 0x849, 0x800001ff}, + { 0x84a, 0x800003ff}, + { 0x84b, 0x800007ff}, + { 0x84c, 0x80000fff}, + { 0x84d, 0x80001fff}, + { 0x84e, 0x80003fff}, + { 0x84f, 0x80007fff}, + { 0xc60, 0x80008000}, + { 0x850, 0x8000ffff}, + { 0xc61, 0x80018001}, + { 0x851, 0x8001ffff}, + { 0xc62, 0x80038003}, + { 0x852, 0x8003ffff}, + { 0xc63, 0x80078007}, + { 0x853, 0x8007ffff}, + { 0xc64, 0x800f800f}, + { 0x854, 0x800fffff}, + { 0xc65, 0x801f801f}, + { 0x855, 0x801fffff}, + { 0xc66, 0x803f803f}, + { 0x856, 0x803fffff}, + { 0xc67, 0x807f807f}, + { 0x857, 0x807fffff}, + { 0xe70, 0x80808080}, + { 0xc68, 0x80ff80ff}, + { 0x858, 0x80ffffff}, + { 0xe71, 0x81818181}, + { 0xc69, 0x81ff81ff}, + { 0x859, 0x81ffffff}, + { 0xe72, 0x83838383}, + { 0xc6a, 0x83ff83ff}, + { 0x85a, 0x83ffffff}, + { 0xe73, 0x87878787}, + { 0xc6b, 0x87ff87ff}, + { 0x85b, 0x87ffffff}, + { 0xf78, 0x88888888}, + { 0xe74, 0x8f8f8f8f}, + { 0xc6c, 0x8fff8fff}, + { 0x85c, 0x8fffffff}, + { 0xf79, 0x99999999}, + { 0xe75, 0x9f9f9f9f}, + { 0xc6d, 0x9fff9fff}, + { 0x85d, 0x9fffffff}, + { 0xffc, 0xaaaaaaaa}, + { 0xf7a, 0xbbbbbbbb}, + { 0xe76, 0xbfbfbfbf}, + { 0xc6e, 0xbfffbfff}, + { 0x85e, 0xbfffffff}, + { 0x881, 0xc0000000}, + { 0x882, 0xc0000001}, + { 0x883, 0xc0000003}, + { 0x884, 0xc0000007}, + { 0x885, 0xc000000f}, + { 0x886, 0xc000001f}, + { 0x887, 0xc000003f}, + { 0x888, 0xc000007f}, + { 0x889, 0xc00000ff}, + { 0x88a, 0xc00001ff}, + { 0x88b, 0xc00003ff}, + { 0x88c, 0xc00007ff}, + { 0x88d, 0xc0000fff}, + { 0x88e, 0xc0001fff}, + { 0x88f, 0xc0003fff}, + { 0x890, 0xc0007fff}, + { 0xca1, 0xc000c000}, + { 0x891, 0xc000ffff}, + { 0xca2, 0xc001c001}, + { 0x892, 0xc001ffff}, + { 0xca3, 0xc003c003}, + { 0x893, 0xc003ffff}, + { 0xca4, 0xc007c007}, + { 0x894, 0xc007ffff}, + { 0xca5, 0xc00fc00f}, + { 0x895, 0xc00fffff}, + { 0xca6, 0xc01fc01f}, + { 0x896, 0xc01fffff}, + { 0xca7, 0xc03fc03f}, + { 0x897, 0xc03fffff}, + { 0xca8, 0xc07fc07f}, + { 0x898, 0xc07fffff}, + { 0xeb1, 0xc0c0c0c0}, + { 0xca9, 0xc0ffc0ff}, + { 0x899, 0xc0ffffff}, + { 0xeb2, 0xc1c1c1c1}, + { 0xcaa, 0xc1ffc1ff}, + { 0x89a, 0xc1ffffff}, + { 0xeb3, 0xc3c3c3c3}, + { 0xcab, 0xc3ffc3ff}, + { 0x89b, 0xc3ffffff}, + { 0xeb4, 0xc7c7c7c7}, + { 0xcac, 0xc7ffc7ff}, + { 0x89c, 0xc7ffffff}, + { 0xfb9, 0xcccccccc}, + { 0xeb5, 0xcfcfcfcf}, + { 0xcad, 0xcfffcfff}, + { 0x89d, 0xcfffffff}, + { 0xfba, 0xdddddddd}, + { 0xeb6, 0xdfdfdfdf}, + { 0xcae, 0xdfffdfff}, + { 0x89e, 0xdfffffff}, + { 0x8c2, 0xe0000000}, + { 0x8c3, 0xe0000001}, + { 0x8c4, 0xe0000003}, + { 0x8c5, 0xe0000007}, + { 0x8c6, 0xe000000f}, + { 0x8c7, 0xe000001f}, + { 0x8c8, 0xe000003f}, + { 0x8c9, 0xe000007f}, + { 0x8ca, 0xe00000ff}, + { 0x8cb, 0xe00001ff}, + { 0x8cc, 0xe00003ff}, + { 0x8cd, 0xe00007ff}, + { 0x8ce, 0xe0000fff}, + { 0x8cf, 0xe0001fff}, + { 0x8d0, 0xe0003fff}, + { 0x8d1, 0xe0007fff}, + { 0xce2, 0xe000e000}, + { 0x8d2, 0xe000ffff}, + { 0xce3, 0xe001e001}, + { 0x8d3, 0xe001ffff}, + { 0xce4, 0xe003e003}, + { 0x8d4, 0xe003ffff}, + { 0xce5, 0xe007e007}, + { 0x8d5, 0xe007ffff}, + { 0xce6, 0xe00fe00f}, + { 0x8d6, 0xe00fffff}, + { 0xce7, 0xe01fe01f}, + { 0x8d7, 0xe01fffff}, + { 0xce8, 0xe03fe03f}, + { 0x8d8, 0xe03fffff}, + { 0xce9, 0xe07fe07f}, + { 0x8d9, 0xe07fffff}, + { 0xef2, 0xe0e0e0e0}, + { 0xcea, 0xe0ffe0ff}, + { 0x8da, 0xe0ffffff}, + { 0xef3, 0xe1e1e1e1}, + { 0xceb, 0xe1ffe1ff}, + { 0x8db, 0xe1ffffff}, + { 0xef4, 0xe3e3e3e3}, + { 0xcec, 0xe3ffe3ff}, + { 0x8dc, 0xe3ffffff}, + { 0xef5, 0xe7e7e7e7}, + { 0xced, 0xe7ffe7ff}, + { 0x8dd, 0xe7ffffff}, + { 0xffa, 0xeeeeeeee}, + { 0xef6, 0xefefefef}, + { 0xcee, 0xefffefff}, + { 0x8de, 0xefffffff}, + { 0x903, 0xf0000000}, + { 0x904, 0xf0000001}, + { 0x905, 0xf0000003}, + { 0x906, 0xf0000007}, + { 0x907, 0xf000000f}, + { 0x908, 0xf000001f}, + { 0x909, 0xf000003f}, + { 0x90a, 0xf000007f}, + { 0x90b, 0xf00000ff}, + { 0x90c, 0xf00001ff}, + { 0x90d, 0xf00003ff}, + { 0x90e, 0xf00007ff}, + { 0x90f, 0xf0000fff}, + { 0x910, 0xf0001fff}, + { 0x911, 0xf0003fff}, + { 0x912, 0xf0007fff}, + { 0xd23, 0xf000f000}, + { 0x913, 0xf000ffff}, + { 0xd24, 0xf001f001}, + { 0x914, 0xf001ffff}, + { 0xd25, 0xf003f003}, + { 0x915, 0xf003ffff}, + { 0xd26, 0xf007f007}, + { 0x916, 0xf007ffff}, + { 0xd27, 0xf00ff00f}, + { 0x917, 0xf00fffff}, + { 0xd28, 0xf01ff01f}, + { 0x918, 0xf01fffff}, + { 0xd29, 0xf03ff03f}, + { 0x919, 0xf03fffff}, + { 0xd2a, 0xf07ff07f}, + { 0x91a, 0xf07fffff}, + { 0xf33, 0xf0f0f0f0}, + { 0xd2b, 0xf0fff0ff}, + { 0x91b, 0xf0ffffff}, + { 0xf34, 0xf1f1f1f1}, + { 0xd2c, 0xf1fff1ff}, + { 0x91c, 0xf1ffffff}, + { 0xf35, 0xf3f3f3f3}, + { 0xd2d, 0xf3fff3ff}, + { 0x91d, 0xf3ffffff}, + { 0xf36, 0xf7f7f7f7}, + { 0xd2e, 0xf7fff7ff}, + { 0x91e, 0xf7ffffff}, + { 0x944, 0xf8000000}, + { 0x945, 0xf8000001}, + { 0x946, 0xf8000003}, + { 0x947, 0xf8000007}, + { 0x948, 0xf800000f}, + { 0x949, 0xf800001f}, + { 0x94a, 0xf800003f}, + { 0x94b, 0xf800007f}, + { 0x94c, 0xf80000ff}, + { 0x94d, 0xf80001ff}, + { 0x94e, 0xf80003ff}, + { 0x94f, 0xf80007ff}, + { 0x950, 0xf8000fff}, + { 0x951, 0xf8001fff}, + { 0x952, 0xf8003fff}, + { 0x953, 0xf8007fff}, + { 0xd64, 0xf800f800}, + { 0x954, 0xf800ffff}, + { 0xd65, 0xf801f801}, + { 0x955, 0xf801ffff}, + { 0xd66, 0xf803f803}, + { 0x956, 0xf803ffff}, + { 0xd67, 0xf807f807}, + { 0x957, 0xf807ffff}, + { 0xd68, 0xf80ff80f}, + { 0x958, 0xf80fffff}, + { 0xd69, 0xf81ff81f}, + { 0x959, 0xf81fffff}, + { 0xd6a, 0xf83ff83f}, + { 0x95a, 0xf83fffff}, + { 0xd6b, 0xf87ff87f}, + { 0x95b, 0xf87fffff}, + { 0xf74, 0xf8f8f8f8}, + { 0xd6c, 0xf8fff8ff}, + { 0x95c, 0xf8ffffff}, + { 0xf75, 0xf9f9f9f9}, + { 0xd6d, 0xf9fff9ff}, + { 0x95d, 0xf9ffffff}, + { 0xf76, 0xfbfbfbfb}, + { 0xd6e, 0xfbfffbff}, + { 0x95e, 0xfbffffff}, + { 0x985, 0xfc000000}, + { 0x986, 0xfc000001}, + { 0x987, 0xfc000003}, + { 0x988, 0xfc000007}, + { 0x989, 0xfc00000f}, + { 0x98a, 0xfc00001f}, + { 0x98b, 0xfc00003f}, + { 0x98c, 0xfc00007f}, + { 0x98d, 0xfc0000ff}, + { 0x98e, 0xfc0001ff}, + { 0x98f, 0xfc0003ff}, + { 0x990, 0xfc0007ff}, + { 0x991, 0xfc000fff}, + { 0x992, 0xfc001fff}, + { 0x993, 0xfc003fff}, + { 0x994, 0xfc007fff}, + { 0xda5, 0xfc00fc00}, + { 0x995, 0xfc00ffff}, + { 0xda6, 0xfc01fc01}, + { 0x996, 0xfc01ffff}, + { 0xda7, 0xfc03fc03}, + { 0x997, 0xfc03ffff}, + { 0xda8, 0xfc07fc07}, + { 0x998, 0xfc07ffff}, + { 0xda9, 0xfc0ffc0f}, + { 0x999, 0xfc0fffff}, + { 0xdaa, 0xfc1ffc1f}, + { 0x99a, 0xfc1fffff}, + { 0xdab, 0xfc3ffc3f}, + { 0x99b, 0xfc3fffff}, + { 0xdac, 0xfc7ffc7f}, + { 0x99c, 0xfc7fffff}, + { 0xfb5, 0xfcfcfcfc}, + { 0xdad, 0xfcfffcff}, + { 0x99d, 0xfcffffff}, + { 0xfb6, 0xfdfdfdfd}, + { 0xdae, 0xfdfffdff}, + { 0x99e, 0xfdffffff}, + { 0x9c6, 0xfe000000}, + { 0x9c7, 0xfe000001}, + { 0x9c8, 0xfe000003}, + { 0x9c9, 0xfe000007}, + { 0x9ca, 0xfe00000f}, + { 0x9cb, 0xfe00001f}, + { 0x9cc, 0xfe00003f}, + { 0x9cd, 0xfe00007f}, + { 0x9ce, 0xfe0000ff}, + { 0x9cf, 0xfe0001ff}, + { 0x9d0, 0xfe0003ff}, + { 0x9d1, 0xfe0007ff}, + { 0x9d2, 0xfe000fff}, + { 0x9d3, 0xfe001fff}, + { 0x9d4, 0xfe003fff}, + { 0x9d5, 0xfe007fff}, + { 0xde6, 0xfe00fe00}, + { 0x9d6, 0xfe00ffff}, + { 0xde7, 0xfe01fe01}, + { 0x9d7, 0xfe01ffff}, + { 0xde8, 0xfe03fe03}, + { 0x9d8, 0xfe03ffff}, + { 0xde9, 0xfe07fe07}, + { 0x9d9, 0xfe07ffff}, + { 0xdea, 0xfe0ffe0f}, + { 0x9da, 0xfe0fffff}, + { 0xdeb, 0xfe1ffe1f}, + { 0x9db, 0xfe1fffff}, + { 0xdec, 0xfe3ffe3f}, + { 0x9dc, 0xfe3fffff}, + { 0xded, 0xfe7ffe7f}, + { 0x9dd, 0xfe7fffff}, + { 0xff6, 0xfefefefe}, + { 0xdee, 0xfefffeff}, + { 0x9de, 0xfeffffff}, + { 0xa07, 0xff000000}, + { 0xa08, 0xff000001}, + { 0xa09, 0xff000003}, + { 0xa0a, 0xff000007}, + { 0xa0b, 0xff00000f}, + { 0xa0c, 0xff00001f}, + { 0xa0d, 0xff00003f}, + { 0xa0e, 0xff00007f}, + { 0xa0f, 0xff0000ff}, + { 0xa10, 0xff0001ff}, + { 0xa11, 0xff0003ff}, + { 0xa12, 0xff0007ff}, + { 0xa13, 0xff000fff}, + { 0xa14, 0xff001fff}, + { 0xa15, 0xff003fff}, + { 0xa16, 0xff007fff}, + { 0xe27, 0xff00ff00}, + { 0xa17, 0xff00ffff}, + { 0xe28, 0xff01ff01}, + { 0xa18, 0xff01ffff}, + { 0xe29, 0xff03ff03}, + { 0xa19, 0xff03ffff}, + { 0xe2a, 0xff07ff07}, + { 0xa1a, 0xff07ffff}, + { 0xe2b, 0xff0fff0f}, + { 0xa1b, 0xff0fffff}, + { 0xe2c, 0xff1fff1f}, + { 0xa1c, 0xff1fffff}, + { 0xe2d, 0xff3fff3f}, + { 0xa1d, 0xff3fffff}, + { 0xe2e, 0xff7fff7f}, + { 0xa1e, 0xff7fffff}, + { 0xa48, 0xff800000}, + { 0xa49, 0xff800001}, + { 0xa4a, 0xff800003}, + { 0xa4b, 0xff800007}, + { 0xa4c, 0xff80000f}, + { 0xa4d, 0xff80001f}, + { 0xa4e, 0xff80003f}, + { 0xa4f, 0xff80007f}, + { 0xa50, 0xff8000ff}, + { 0xa51, 0xff8001ff}, + { 0xa52, 0xff8003ff}, + { 0xa53, 0xff8007ff}, + { 0xa54, 0xff800fff}, + { 0xa55, 0xff801fff}, + { 0xa56, 0xff803fff}, + { 0xa57, 0xff807fff}, + { 0xe68, 0xff80ff80}, + { 0xa58, 0xff80ffff}, + { 0xe69, 0xff81ff81}, + { 0xa59, 0xff81ffff}, + { 0xe6a, 0xff83ff83}, + { 0xa5a, 0xff83ffff}, + { 0xe6b, 0xff87ff87}, + { 0xa5b, 0xff87ffff}, + { 0xe6c, 0xff8fff8f}, + { 0xa5c, 0xff8fffff}, + { 0xe6d, 0xff9fff9f}, + { 0xa5d, 0xff9fffff}, + { 0xe6e, 0xffbfffbf}, + { 0xa5e, 0xffbfffff}, + { 0xa89, 0xffc00000}, + { 0xa8a, 0xffc00001}, + { 0xa8b, 0xffc00003}, + { 0xa8c, 0xffc00007}, + { 0xa8d, 0xffc0000f}, + { 0xa8e, 0xffc0001f}, + { 0xa8f, 0xffc0003f}, + { 0xa90, 0xffc0007f}, + { 0xa91, 0xffc000ff}, + { 0xa92, 0xffc001ff}, + { 0xa93, 0xffc003ff}, + { 0xa94, 0xffc007ff}, + { 0xa95, 0xffc00fff}, + { 0xa96, 0xffc01fff}, + { 0xa97, 0xffc03fff}, + { 0xa98, 0xffc07fff}, + { 0xea9, 0xffc0ffc0}, + { 0xa99, 0xffc0ffff}, + { 0xeaa, 0xffc1ffc1}, + { 0xa9a, 0xffc1ffff}, + { 0xeab, 0xffc3ffc3}, + { 0xa9b, 0xffc3ffff}, + { 0xeac, 0xffc7ffc7}, + { 0xa9c, 0xffc7ffff}, + { 0xead, 0xffcfffcf}, + { 0xa9d, 0xffcfffff}, + { 0xeae, 0xffdfffdf}, + { 0xa9e, 0xffdfffff}, + { 0xaca, 0xffe00000}, + { 0xacb, 0xffe00001}, + { 0xacc, 0xffe00003}, + { 0xacd, 0xffe00007}, + { 0xace, 0xffe0000f}, + { 0xacf, 0xffe0001f}, + { 0xad0, 0xffe0003f}, + { 0xad1, 0xffe0007f}, + { 0xad2, 0xffe000ff}, + { 0xad3, 0xffe001ff}, + { 0xad4, 0xffe003ff}, + { 0xad5, 0xffe007ff}, + { 0xad6, 0xffe00fff}, + { 0xad7, 0xffe01fff}, + { 0xad8, 0xffe03fff}, + { 0xad9, 0xffe07fff}, + { 0xeea, 0xffe0ffe0}, + { 0xada, 0xffe0ffff}, + { 0xeeb, 0xffe1ffe1}, + { 0xadb, 0xffe1ffff}, + { 0xeec, 0xffe3ffe3}, + { 0xadc, 0xffe3ffff}, + { 0xeed, 0xffe7ffe7}, + { 0xadd, 0xffe7ffff}, + { 0xeee, 0xffefffef}, + { 0xade, 0xffefffff}, + { 0xb0b, 0xfff00000}, + { 0xb0c, 0xfff00001}, + { 0xb0d, 0xfff00003}, + { 0xb0e, 0xfff00007}, + { 0xb0f, 0xfff0000f}, + { 0xb10, 0xfff0001f}, + { 0xb11, 0xfff0003f}, + { 0xb12, 0xfff0007f}, + { 0xb13, 0xfff000ff}, + { 0xb14, 0xfff001ff}, + { 0xb15, 0xfff003ff}, + { 0xb16, 0xfff007ff}, + { 0xb17, 0xfff00fff}, + { 0xb18, 0xfff01fff}, + { 0xb19, 0xfff03fff}, + { 0xb1a, 0xfff07fff}, + { 0xf2b, 0xfff0fff0}, + { 0xb1b, 0xfff0ffff}, + { 0xf2c, 0xfff1fff1}, + { 0xb1c, 0xfff1ffff}, + { 0xf2d, 0xfff3fff3}, + { 0xb1d, 0xfff3ffff}, + { 0xf2e, 0xfff7fff7}, + { 0xb1e, 0xfff7ffff}, + { 0xb4c, 0xfff80000}, + { 0xb4d, 0xfff80001}, + { 0xb4e, 0xfff80003}, + { 0xb4f, 0xfff80007}, + { 0xb50, 0xfff8000f}, + { 0xb51, 0xfff8001f}, + { 0xb52, 0xfff8003f}, + { 0xb53, 0xfff8007f}, + { 0xb54, 0xfff800ff}, + { 0xb55, 0xfff801ff}, + { 0xb56, 0xfff803ff}, + { 0xb57, 0xfff807ff}, + { 0xb58, 0xfff80fff}, + { 0xb59, 0xfff81fff}, + { 0xb5a, 0xfff83fff}, + { 0xb5b, 0xfff87fff}, + { 0xf6c, 0xfff8fff8}, + { 0xb5c, 0xfff8ffff}, + { 0xf6d, 0xfff9fff9}, + { 0xb5d, 0xfff9ffff}, + { 0xf6e, 0xfffbfffb}, + { 0xb5e, 0xfffbffff}, + { 0xb8d, 0xfffc0000}, + { 0xb8e, 0xfffc0001}, + { 0xb8f, 0xfffc0003}, + { 0xb90, 0xfffc0007}, + { 0xb91, 0xfffc000f}, + { 0xb92, 0xfffc001f}, + { 0xb93, 0xfffc003f}, + { 0xb94, 0xfffc007f}, + { 0xb95, 0xfffc00ff}, + { 0xb96, 0xfffc01ff}, + { 0xb97, 0xfffc03ff}, + { 0xb98, 0xfffc07ff}, + { 0xb99, 0xfffc0fff}, + { 0xb9a, 0xfffc1fff}, + { 0xb9b, 0xfffc3fff}, + { 0xb9c, 0xfffc7fff}, + { 0xfad, 0xfffcfffc}, + { 0xb9d, 0xfffcffff}, + { 0xfae, 0xfffdfffd}, + { 0xb9e, 0xfffdffff}, + { 0xbce, 0xfffe0000}, + { 0xbcf, 0xfffe0001}, + { 0xbd0, 0xfffe0003}, + { 0xbd1, 0xfffe0007}, + { 0xbd2, 0xfffe000f}, + { 0xbd3, 0xfffe001f}, + { 0xbd4, 0xfffe003f}, + { 0xbd5, 0xfffe007f}, + { 0xbd6, 0xfffe00ff}, + { 0xbd7, 0xfffe01ff}, + { 0xbd8, 0xfffe03ff}, + { 0xbd9, 0xfffe07ff}, + { 0xbda, 0xfffe0fff}, + { 0xbdb, 0xfffe1fff}, + { 0xbdc, 0xfffe3fff}, + { 0xbdd, 0xfffe7fff}, + { 0xfee, 0xfffefffe}, + { 0xbde, 0xfffeffff}, + { 0xc0f, 0xffff0000}, + { 0xc10, 0xffff0001}, + { 0xc11, 0xffff0003}, + { 0xc12, 0xffff0007}, + { 0xc13, 0xffff000f}, + { 0xc14, 0xffff001f}, + { 0xc15, 0xffff003f}, + { 0xc16, 0xffff007f}, + { 0xc17, 0xffff00ff}, + { 0xc18, 0xffff01ff}, + { 0xc19, 0xffff03ff}, + { 0xc1a, 0xffff07ff}, + { 0xc1b, 0xffff0fff}, + { 0xc1c, 0xffff1fff}, + { 0xc1d, 0xffff3fff}, + { 0xc1e, 0xffff7fff}, + { 0xc50, 0xffff8000}, + { 0xc51, 0xffff8001}, + { 0xc52, 0xffff8003}, + { 0xc53, 0xffff8007}, + { 0xc54, 0xffff800f}, + { 0xc55, 0xffff801f}, + { 0xc56, 0xffff803f}, + { 0xc57, 0xffff807f}, + { 0xc58, 0xffff80ff}, + { 0xc59, 0xffff81ff}, + { 0xc5a, 0xffff83ff}, + { 0xc5b, 0xffff87ff}, + { 0xc5c, 0xffff8fff}, + { 0xc5d, 0xffff9fff}, + { 0xc5e, 0xffffbfff}, + { 0xc91, 0xffffc000}, + { 0xc92, 0xffffc001}, + { 0xc93, 0xffffc003}, + { 0xc94, 0xffffc007}, + { 0xc95, 0xffffc00f}, + { 0xc96, 0xffffc01f}, + { 0xc97, 0xffffc03f}, + { 0xc98, 0xffffc07f}, + { 0xc99, 0xffffc0ff}, + { 0xc9a, 0xffffc1ff}, + { 0xc9b, 0xffffc3ff}, + { 0xc9c, 0xffffc7ff}, + { 0xc9d, 0xffffcfff}, + { 0xc9e, 0xffffdfff}, + { 0xcd2, 0xffffe000}, + { 0xcd3, 0xffffe001}, + { 0xcd4, 0xffffe003}, + { 0xcd5, 0xffffe007}, + { 0xcd6, 0xffffe00f}, + { 0xcd7, 0xffffe01f}, + { 0xcd8, 0xffffe03f}, + { 0xcd9, 0xffffe07f}, + { 0xcda, 0xffffe0ff}, + { 0xcdb, 0xffffe1ff}, + { 0xcdc, 0xffffe3ff}, + { 0xcdd, 0xffffe7ff}, + { 0xcde, 0xffffefff}, + { 0xd13, 0xfffff000}, + { 0xd14, 0xfffff001}, + { 0xd15, 0xfffff003}, + { 0xd16, 0xfffff007}, + { 0xd17, 0xfffff00f}, + { 0xd18, 0xfffff01f}, + { 0xd19, 0xfffff03f}, + { 0xd1a, 0xfffff07f}, + { 0xd1b, 0xfffff0ff}, + { 0xd1c, 0xfffff1ff}, + { 0xd1d, 0xfffff3ff}, + { 0xd1e, 0xfffff7ff}, + { 0xd54, 0xfffff800}, + { 0xd55, 0xfffff801}, + { 0xd56, 0xfffff803}, + { 0xd57, 0xfffff807}, + { 0xd58, 0xfffff80f}, + { 0xd59, 0xfffff81f}, + { 0xd5a, 0xfffff83f}, + { 0xd5b, 0xfffff87f}, + { 0xd5c, 0xfffff8ff}, + { 0xd5d, 0xfffff9ff}, + { 0xd5e, 0xfffffbff}, + { 0xd95, 0xfffffc00}, + { 0xd96, 0xfffffc01}, + { 0xd97, 0xfffffc03}, + { 0xd98, 0xfffffc07}, + { 0xd99, 0xfffffc0f}, + { 0xd9a, 0xfffffc1f}, + { 0xd9b, 0xfffffc3f}, + { 0xd9c, 0xfffffc7f}, + { 0xd9d, 0xfffffcff}, + { 0xd9e, 0xfffffdff}, + { 0xdd6, 0xfffffe00}, + { 0xdd7, 0xfffffe01}, + { 0xdd8, 0xfffffe03}, + { 0xdd9, 0xfffffe07}, + { 0xdda, 0xfffffe0f}, + { 0xddb, 0xfffffe1f}, + { 0xddc, 0xfffffe3f}, + { 0xddd, 0xfffffe7f}, + { 0xdde, 0xfffffeff}, + { 0xe17, 0xffffff00}, + { 0xe18, 0xffffff01}, + { 0xe19, 0xffffff03}, + { 0xe1a, 0xffffff07}, + { 0xe1b, 0xffffff0f}, + { 0xe1c, 0xffffff1f}, + { 0xe1d, 0xffffff3f}, + { 0xe1e, 0xffffff7f}, + { 0xe58, 0xffffff80}, + { 0xe59, 0xffffff81}, + { 0xe5a, 0xffffff83}, + { 0xe5b, 0xffffff87}, + { 0xe5c, 0xffffff8f}, + { 0xe5d, 0xffffff9f}, + { 0xe5e, 0xffffffbf}, + { 0xe99, 0xffffffc0}, + { 0xe9a, 0xffffffc1}, + { 0xe9b, 0xffffffc3}, + { 0xe9c, 0xffffffc7}, + { 0xe9d, 0xffffffcf}, + { 0xe9e, 0xffffffdf}, + { 0xeda, 0xffffffe0}, + { 0xedb, 0xffffffe1}, + { 0xedc, 0xffffffe3}, + { 0xedd, 0xffffffe7}, + { 0xede, 0xffffffef}, + { 0xf1b, 0xfffffff0}, + { 0xf1c, 0xfffffff1}, + { 0xf1d, 0xfffffff3}, + { 0xf1e, 0xfffffff7}, + { 0xf5c, 0xfffffff8}, + { 0xf5d, 0xfffffff9}, + { 0xf5e, 0xfffffffb}, + { 0xf9d, 0xfffffffc}, + { 0xf9e, 0xfffffffd}, + { 0xfde, 0xfffffffe}, }; -uint32_t host_arm64_find_imm(uint32_t data) +uint32_t +host_arm64_find_imm(uint32_t data) { - int l = 0, r = IMM_NR - 1; + int l = 0, r = IMM_NR - 1; - while (l <= r) - { - int m = (l + r) >> 1; + while (l <= r) { + int m = (l + r) >> 1; - if (imm_table[m][1] < data) - l = m+1; - else if (imm_table[m][1] > data) - r = m-1; - else - return imm_table[m][0]; - } - return 0; + if (imm_table[m][1] < data) + l = m + 1; + else if (imm_table[m][1] > data) + r = m - 1; + else + return imm_table[m][0]; + } + return 0; } diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index 0cc20d788..aa5e5870a 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -1,1380 +1,1516 @@ #if defined __aarch64__ || defined _M_ARM64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm64_defs.h" -#include "codegen_backend_arm64_ops.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm64_defs.h" +# include "codegen_backend_arm64_ops.h" +# define Rt(x) (x) +# define Rd(x) (x) +# define Rn(x) ((x) << 5) +# define Rt2(x) ((x) << 10) +# define Rm(x) ((x) << 16) -#define Rt(x) (x) -#define Rd(x) (x) -#define Rn(x) ((x) << 5) -#define Rt2(x) ((x) << 10) -#define Rm(x) ((x) << 16) +# define shift_imm6(x) ((x) << 10) -#define shift_imm6(x) ((x) << 10) +# define DATA_OFFSET_UP (1 << 23) +# define DATA_OFFSET_DOWN (0 << 23) -#define DATA_OFFSET_UP (1 << 23) -#define DATA_OFFSET_DOWN (0 << 23) +# define COND_EQ (0x0) +# define COND_NE (0x1) +# define COND_CS (0x2) +# define COND_CC (0x3) +# define COND_MI (0x4) +# define COND_PL (0x5) +# define COND_VS (0x6) +# define COND_VC (0x7) +# define COND_HI (0x8) +# define COND_LS (0x9) +# define COND_GE (0xa) +# define COND_LT (0xb) +# define COND_GT (0xc) +# define COND_LE (0xd) -#define COND_EQ (0x0) -#define COND_NE (0x1) -#define COND_CS (0x2) -#define COND_CC (0x3) -#define COND_MI (0x4) -#define COND_PL (0x5) -#define COND_VS (0x6) -#define COND_VC (0x7) -#define COND_HI (0x8) -#define COND_LS (0x9) -#define COND_GE (0xa) -#define COND_LT (0xb) -#define COND_GT (0xc) -#define COND_LE (0xd) +# define CSEL_COND(cond) ((cond) << 12) -#define CSEL_COND(cond) ((cond) << 12) +# define OPCODE_SHIFT 24 +# define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) +# define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT) +# define OPCODE_ADR (0x10 << OPCODE_SHIFT) +# define OPCODE_B (0x14 << OPCODE_SHIFT) +# define OPCODE_BCOND (0x54 << OPCODE_SHIFT) +# define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) +# define OPCODE_CBZ (0xb4 << OPCODE_SHIFT) +# define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) +# define OPCODE_CMNX_IMM (0xb1 << OPCODE_SHIFT) +# define OPCODE_CMP_IMM (0x71 << OPCODE_SHIFT) +# define OPCODE_CMPX_IMM (0xf1 << OPCODE_SHIFT) +# define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) +# define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT) +# define OPCODE_TBNZ (0x37 << OPCODE_SHIFT) +# define OPCODE_TBZ (0x36 << OPCODE_SHIFT) -#define OPCODE_SHIFT 24 -#define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) -#define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT) -#define OPCODE_ADR (0x10 << OPCODE_SHIFT) -#define OPCODE_B (0x14 << OPCODE_SHIFT) -#define OPCODE_BCOND (0x54 << OPCODE_SHIFT) -#define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) -#define OPCODE_CBZ (0xb4 << OPCODE_SHIFT) -#define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) -#define OPCODE_CMNX_IMM (0xb1 << OPCODE_SHIFT) -#define OPCODE_CMP_IMM (0x71 << OPCODE_SHIFT) -#define OPCODE_CMPX_IMM (0xf1 << OPCODE_SHIFT) -#define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) -#define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT) -#define OPCODE_TBNZ (0x37 << OPCODE_SHIFT) -#define OPCODE_TBZ (0x36 << OPCODE_SHIFT) +# define OPCODE_AND_IMM (0x024 << 23) +# define OPCODE_ANDS_IMM (0x0e4 << 23) +# define OPCODE_EOR_IMM (0x0a4 << 23) +# define OPCODE_MOVK_W (0x0e5 << 23) +# define OPCODE_MOVK_X (0x1e5 << 23) +# define OPCODE_MOVZ_W (0x0a5 << 23) +# define OPCODE_MOVZ_X (0x1a5 << 23) +# define OPCODE_ORR_IMM (0x064 << 23) -#define OPCODE_AND_IMM (0x024 << 23) -#define OPCODE_ANDS_IMM (0x0e4 << 23) -#define OPCODE_EOR_IMM (0x0a4 << 23) -#define OPCODE_MOVK_W (0x0e5 << 23) -#define OPCODE_MOVK_X (0x1e5 << 23) -#define OPCODE_MOVZ_W (0x0a5 << 23) -#define OPCODE_MOVZ_X (0x1a5 << 23) -#define OPCODE_ORR_IMM (0x064 << 23) +# define OPCODE_BFI (0x0cc << 22) +# define OPCODE_LDR_IMM_W (0x2e5 << 22) +# define OPCODE_LDR_IMM_X (0x3e5 << 22) +# define OPCODE_LDR_IMM_F64 (0x3f5 << 22) +# define OPCODE_LDRB_IMM_W (0x0e5 << 22) +# define OPCODE_LDRH_IMM (0x1e5 << 22) +# define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) +# define OPCODE_SBFX (0x04c << 22) +# define OPCODE_STP_PREIDX_X (0x2a6 << 22) +# define OPCODE_STR_IMM_W (0x2e4 << 22) +# define OPCODE_STR_IMM_Q (0x3e4 << 22) +# define OPCODE_STR_IMM_F64 (0x3f4 << 22) +# define OPCODE_STRB_IMM (0x0e4 << 22) +# define OPCODE_STRH_IMM (0x1e4 << 22) +# define OPCODE_UBFX (0x14c << 22) -#define OPCODE_BFI (0x0cc << 22) -#define OPCODE_LDR_IMM_W (0x2e5 << 22) -#define OPCODE_LDR_IMM_X (0x3e5 << 22) -#define OPCODE_LDR_IMM_F64 (0x3f5 << 22) -#define OPCODE_LDRB_IMM_W (0x0e5 << 22) -#define OPCODE_LDRH_IMM (0x1e5 << 22) -#define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) -#define OPCODE_SBFX (0x04c << 22) -#define OPCODE_STP_PREIDX_X (0x2a6 << 22) -#define OPCODE_STR_IMM_W (0x2e4 << 22) -#define OPCODE_STR_IMM_Q (0x3e4 << 22) -#define OPCODE_STR_IMM_F64 (0x3f4 << 22) -#define OPCODE_STRB_IMM (0x0e4 << 22) -#define OPCODE_STRH_IMM (0x1e4 << 22) -#define OPCODE_UBFX (0x14c << 22) +# define OPCODE_ADD_LSL (0x058 << 21) +# define OPCODE_ADD_LSR (0x05a << 21) +# define OPCODE_ADDX_LSL (0x458 << 21) +# define OPCODE_AND_ASR (0x054 << 21) +# define OPCODE_AND_LSL (0x050 << 21) +# define OPCODE_AND_ROR (0x056 << 21) +# define OPCODE_ANDS_LSL (0x350 << 21) +# define OPCODE_CMP_LSL (0x358 << 21) +# define OPCODE_CSEL (0x0d4 << 21) +# define OPCODE_EOR_LSL (0x250 << 21) +# define OPCODE_ORR_ASR (0x154 << 21) +# define OPCODE_ORR_LSL (0x150 << 21) +# define OPCODE_ORR_LSR (0x152 << 21) +# define OPCODE_ORR_ROR (0x156 << 21) +# define OPCODE_ORRX_LSL (0x550 << 21) +# define OPCODE_SUB_LSL (0x258 << 21) +# define OPCODE_SUB_LSR (0x25a << 21) +# define OPCODE_SUBX_LSL (0x658 << 21) -#define OPCODE_ADD_LSL (0x058 << 21) -#define OPCODE_ADD_LSR (0x05a << 21) -#define OPCODE_ADDX_LSL (0x458 << 21) -#define OPCODE_AND_ASR (0x054 << 21) -#define OPCODE_AND_LSL (0x050 << 21) -#define OPCODE_AND_ROR (0x056 << 21) -#define OPCODE_ANDS_LSL (0x350 << 21) -#define OPCODE_CMP_LSL (0x358 << 21) -#define OPCODE_CSEL (0x0d4 << 21) -#define OPCODE_EOR_LSL (0x250 << 21) -#define OPCODE_ORR_ASR (0x154 << 21) -#define OPCODE_ORR_LSL (0x150 << 21) -#define OPCODE_ORR_LSR (0x152 << 21) -#define OPCODE_ORR_ROR (0x156 << 21) -#define OPCODE_ORRX_LSL (0x550 << 21) -#define OPCODE_SUB_LSL (0x258 << 21) -#define OPCODE_SUB_LSR (0x25a << 21) -#define OPCODE_SUBX_LSL (0x658 << 21) +# define OPCODE_ADD_V8B (0x0e208400) +# define OPCODE_ADD_V4H (0x0e608400) +# define OPCODE_ADD_V2S (0x0ea08400) +# define OPCODE_ADDP_V4S (0x4ea0bc00) +# define OPCODE_AND_V (0x0e201c00) +# define OPCODE_ASR (0x1ac02800) +# define OPCODE_BIC_V (0x0e601c00) +# define OPCODE_BLR (0xd63f0000) +# define OPCODE_BR (0xd61f0000) +# define OPCODE_CMEQ_V8B (0x2e208c00) +# define OPCODE_CMEQ_V4H (0x2e608c00) +# define OPCODE_CMEQ_V2S (0x2ea08c00) +# define OPCODE_CMGT_V8B (0x0e203400) +# define OPCODE_CMGT_V4H (0x0e603400) +# define OPCODE_CMGT_V2S (0x0ea03400) +# define OPCODE_DUP_V2S (0x0e040400) +# define OPCODE_EOR_V (0x2e201c00) +# define OPCODE_FABS_D (0x1e60c000) +# define OPCODE_FADD_D (0x1e602800) +# define OPCODE_FADD_V2S (0x0e20d400) +# define OPCODE_FCMEQ_V2S (0x0e20e400) +# define OPCODE_FCMGE_V2S (0x2e20e400) +# define OPCODE_FCMGT_V2S (0x2ea0e400) +# define OPCODE_FCMP_D (0x1e602000) +# define OPCODE_FCVT_D_S (0x1e22c000) +# define OPCODE_FCVT_S_D (0x1e624000) +# define OPCODE_FCVTMS_W_D (0x1e700000) +# define OPCODE_FCVTMS_X_D (0x9e700000) +# define OPCODE_FCVTNS_W_D (0x1e600000) +# define OPCODE_FCVTNS_X_D (0x9e600000) +# define OPCODE_FCVTPS_W_D (0x1e680000) +# define OPCODE_FCVTPS_X_D (0x9e680000) +# define OPCODE_FCVTZS_W_D (0x1e780000) +# define OPCODE_FCVTZS_X_D (0x9e780000) +# define OPCODE_FCVTZS_V2S (0x0ea1b800) +# define OPCODE_FDIV_D (0x1e601800) +# define OPCODE_FDIV_S (0x1e201800) +# define OPCODE_FMAX_V2S (0x0e20f400) +# define OPCODE_FMIN_V2S (0x0ea0f400) +# define OPCODE_FMOV_D_D (0x1e604000) +# define OPCODE_FMOV_D_Q (0x9e670000) +# define OPCODE_FMOV_Q_D (0x9e660000) +# define OPCODE_FMOV_S_W (0x1e270000) +# define OPCODE_FMOV_W_S (0x1e260000) +# define OPCODE_FMOV_S_ONE (0x1e2e1000) +# define OPCODE_FMUL_D (0x1e600800) +# define OPCODE_FMUL_V2S (0x2e20dc00) +# define OPCODE_FNEG_D (0x1e614000) +# define OPCODE_FRINTX_D (0x1e674000) +# define OPCODE_FSQRT_D (0x1e61c000) +# define OPCODE_FSQRT_S (0x1e21c000) +# define OPCODE_FSUB_D (0x1e603800) +# define OPCODE_FSUB_V2S (0x0ea0d400) +# define OPCODE_LDR_REG (0xb8606800) +# define OPCODE_LDRX_REG (0xf8606800) +# define OPCODE_LDRB_REG (0x38606800) +# define OPCODE_LDRH_REG (0x78606800) +# define OPCODE_LDRX_REG_LSL3 (0xf8607800) +# define OPCODE_LDR_REG_F32 (0xbc606800) +# define OPCODE_LDR_REG_F64 (0xfc606800) +# define OPCODE_LDR_REG_F64_S (0xfc607800) +# define OPCODE_LSL (0x1ac02000) +# define OPCODE_LSR (0x1ac02400) +# define OPCODE_MSR_FPCR (0xd51b4400) +# define OPCODE_MUL_V4H (0x0e609c00) +# define OPCODE_NOP (0xd503201f) +# define OPCODE_ORR_V (0x0ea01c00) +# define OPCODE_RET (0xd65f0000) +# define OPCODE_ROR (0x1ac02c00) +# define OPCODE_SADDLP_V2S_4H (0x0e602800) +# define OPCODE_SCVTF_D_Q (0x9e620000) +# define OPCODE_SCVTF_D_W (0x1e620000) +# define OPCODE_SCVTF_V2S (0x0e21d800) +# define OPCODE_SQADD_V8B (0x0e200c00) +# define OPCODE_SQADD_V4H (0x0e600c00) +# define OPCODE_SQSUB_V8B (0x0e202c00) +# define OPCODE_SQSUB_V4H (0x0e602c00) +# define OPCODE_SQXTN_V8B_8H (0x0e214800) +# define OPCODE_SQXTN_V4H_4S (0x0e614800) +# define OPCODE_SHL_VD (0x0f005400) +# define OPCODE_SHL_VQ (0x4f005400) +# define OPCODE_SHRN (0x0f008400) +# define OPCODE_SMULL_V4S_4H (0x0e60c000) +# define OPCODE_SSHR_VD (0x0f000400) +# define OPCODE_SSHR_VQ (0x4f000400) +# define OPCODE_STR_REG (0xb8206800) +# define OPCODE_STRB_REG (0x38206800) +# define OPCODE_STRH_REG (0x78206800) +# define OPCODE_STR_REG_F32 (0xbc206800) +# define OPCODE_STR_REG_F64 (0xfc206800) +# define OPCODE_STR_REG_F64_S (0xfc207800) +# define OPCODE_SUB_V8B (0x2e208400) +# define OPCODE_SUB_V4H (0x2e608400) +# define OPCODE_SUB_V2S (0x2ea08400) +# define OPCODE_UQADD_V8B (0x2e200c00) +# define OPCODE_UQADD_V4H (0x2e600c00) +# define OPCODE_UQSUB_V8B (0x2e202c00) +# define OPCODE_UQSUB_V4H (0x2e602c00) +# define OPCODE_UQXTN_V8B_8H (0x2e214800) +# define OPCODE_UQXTN_V4H_4S (0x2e614800) +# define OPCODE_USHR_VD (0x2f000400) +# define OPCODE_USHR_VQ (0x6f000400) +# define OPCODE_ZIP1_V8B (0x0e003800) +# define OPCODE_ZIP1_V4H (0x0e403800) +# define OPCODE_ZIP1_V2S (0x0e803800) +# define OPCODE_ZIP2_V8B (0x0e007800) +# define OPCODE_ZIP2_V4H (0x0e407800) +# define OPCODE_ZIP2_V2S (0x0e807800) -#define OPCODE_ADD_V8B (0x0e208400) -#define OPCODE_ADD_V4H (0x0e608400) -#define OPCODE_ADD_V2S (0x0ea08400) -#define OPCODE_ADDP_V4S (0x4ea0bc00) -#define OPCODE_AND_V (0x0e201c00) -#define OPCODE_ASR (0x1ac02800) -#define OPCODE_BIC_V (0x0e601c00) -#define OPCODE_BLR (0xd63f0000) -#define OPCODE_BR (0xd61f0000) -#define OPCODE_CMEQ_V8B (0x2e208c00) -#define OPCODE_CMEQ_V4H (0x2e608c00) -#define OPCODE_CMEQ_V2S (0x2ea08c00) -#define OPCODE_CMGT_V8B (0x0e203400) -#define OPCODE_CMGT_V4H (0x0e603400) -#define OPCODE_CMGT_V2S (0x0ea03400) -#define OPCODE_DUP_V2S (0x0e040400) -#define OPCODE_EOR_V (0x2e201c00) -#define OPCODE_FABS_D (0x1e60c000) -#define OPCODE_FADD_D (0x1e602800) -#define OPCODE_FADD_V2S (0x0e20d400) -#define OPCODE_FCMEQ_V2S (0x0e20e400) -#define OPCODE_FCMGE_V2S (0x2e20e400) -#define OPCODE_FCMGT_V2S (0x2ea0e400) -#define OPCODE_FCMP_D (0x1e602000) -#define OPCODE_FCVT_D_S (0x1e22c000) -#define OPCODE_FCVT_S_D (0x1e624000) -#define OPCODE_FCVTMS_W_D (0x1e700000) -#define OPCODE_FCVTMS_X_D (0x9e700000) -#define OPCODE_FCVTNS_W_D (0x1e600000) -#define OPCODE_FCVTNS_X_D (0x9e600000) -#define OPCODE_FCVTPS_W_D (0x1e680000) -#define OPCODE_FCVTPS_X_D (0x9e680000) -#define OPCODE_FCVTZS_W_D (0x1e780000) -#define OPCODE_FCVTZS_X_D (0x9e780000) -#define OPCODE_FCVTZS_V2S (0x0ea1b800) -#define OPCODE_FDIV_D (0x1e601800) -#define OPCODE_FDIV_S (0x1e201800) -#define OPCODE_FMAX_V2S (0x0e20f400) -#define OPCODE_FMIN_V2S (0x0ea0f400) -#define OPCODE_FMOV_D_D (0x1e604000) -#define OPCODE_FMOV_D_Q (0x9e670000) -#define OPCODE_FMOV_Q_D (0x9e660000) -#define OPCODE_FMOV_S_W (0x1e270000) -#define OPCODE_FMOV_W_S (0x1e260000) -#define OPCODE_FMOV_S_ONE (0x1e2e1000) -#define OPCODE_FMUL_D (0x1e600800) -#define OPCODE_FMUL_V2S (0x2e20dc00) -#define OPCODE_FNEG_D (0x1e614000) -#define OPCODE_FRINTX_D (0x1e674000) -#define OPCODE_FSQRT_D (0x1e61c000) -#define OPCODE_FSQRT_S (0x1e21c000) -#define OPCODE_FSUB_D (0x1e603800) -#define OPCODE_FSUB_V2S (0x0ea0d400) -#define OPCODE_LDR_REG (0xb8606800) -#define OPCODE_LDRX_REG (0xf8606800) -#define OPCODE_LDRB_REG (0x38606800) -#define OPCODE_LDRH_REG (0x78606800) -#define OPCODE_LDRX_REG_LSL3 (0xf8607800) -#define OPCODE_LDR_REG_F32 (0xbc606800) -#define OPCODE_LDR_REG_F64 (0xfc606800) -#define OPCODE_LDR_REG_F64_S (0xfc607800) -#define OPCODE_LSL (0x1ac02000) -#define OPCODE_LSR (0x1ac02400) -#define OPCODE_MSR_FPCR (0xd51b4400) -#define OPCODE_MUL_V4H (0x0e609c00) -#define OPCODE_NOP (0xd503201f) -#define OPCODE_ORR_V (0x0ea01c00) -#define OPCODE_RET (0xd65f0000) -#define OPCODE_ROR (0x1ac02c00) -#define OPCODE_SADDLP_V2S_4H (0x0e602800) -#define OPCODE_SCVTF_D_Q (0x9e620000) -#define OPCODE_SCVTF_D_W (0x1e620000) -#define OPCODE_SCVTF_V2S (0x0e21d800) -#define OPCODE_SQADD_V8B (0x0e200c00) -#define OPCODE_SQADD_V4H (0x0e600c00) -#define OPCODE_SQSUB_V8B (0x0e202c00) -#define OPCODE_SQSUB_V4H (0x0e602c00) -#define OPCODE_SQXTN_V8B_8H (0x0e214800) -#define OPCODE_SQXTN_V4H_4S (0x0e614800) -#define OPCODE_SHL_VD (0x0f005400) -#define OPCODE_SHL_VQ (0x4f005400) -#define OPCODE_SHRN (0x0f008400) -#define OPCODE_SMULL_V4S_4H (0x0e60c000) -#define OPCODE_SSHR_VD (0x0f000400) -#define OPCODE_SSHR_VQ (0x4f000400) -#define OPCODE_STR_REG (0xb8206800) -#define OPCODE_STRB_REG (0x38206800) -#define OPCODE_STRH_REG (0x78206800) -#define OPCODE_STR_REG_F32 (0xbc206800) -#define OPCODE_STR_REG_F64 (0xfc206800) -#define OPCODE_STR_REG_F64_S (0xfc207800) -#define OPCODE_SUB_V8B (0x2e208400) -#define OPCODE_SUB_V4H (0x2e608400) -#define OPCODE_SUB_V2S (0x2ea08400) -#define OPCODE_UQADD_V8B (0x2e200c00) -#define OPCODE_UQADD_V4H (0x2e600c00) -#define OPCODE_UQSUB_V8B (0x2e202c00) -#define OPCODE_UQSUB_V4H (0x2e602c00) -#define OPCODE_UQXTN_V8B_8H (0x2e214800) -#define OPCODE_UQXTN_V4H_4S (0x2e614800) -#define OPCODE_USHR_VD (0x2f000400) -#define OPCODE_USHR_VQ (0x6f000400) -#define OPCODE_ZIP1_V8B (0x0e003800) -#define OPCODE_ZIP1_V4H (0x0e403800) -#define OPCODE_ZIP1_V2S (0x0e803800) -#define OPCODE_ZIP2_V8B (0x0e007800) -#define OPCODE_ZIP2_V4H (0x0e407800) -#define OPCODE_ZIP2_V2S (0x0e807800) +# define DATPROC_SHIFT(sh) (sh << 10) +# define DATPROC_IMM_SHIFT(sh) (sh << 22) +# define MOV_WIDE_HW(hw) (hw << 21) -#define DATPROC_SHIFT(sh) (sh << 10) -#define DATPROC_IMM_SHIFT(sh) (sh << 22) -#define MOV_WIDE_HW(hw) (hw << 21) +# define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) +# define IMM12(imm_data) ((imm_data) << 10) +# define IMM16(imm_data) ((imm_data) << 5) -#define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) -#define IMM12(imm_data) ((imm_data) << 10) -#define IMM16(imm_data) ((imm_data) << 5) +# define IMMN(immn) ((immn) << 22) +# define IMMR(immr) ((immr) << 16) +# define IMMS(imms) ((imms) << 10) -#define IMMN(immn) ((immn) << 22) -#define IMMR(immr) ((immr) << 16) -#define IMMS(imms) ((imms) << 10) +# define IMM_LOGICAL(imm) ((imm) << 10) -#define IMM_LOGICAL(imm) ((imm) << 10) +# define BIT_TBxZ(bit) ((((bit) &0x1f) << 19) | (((bit) &0x20) ? (1 << 31) : 0)) -#define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) +# define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) +# define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) +# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) &0x1fffff) >> 2) << 5)) +# define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) -#define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) -#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) -#define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) & 0x1fffff) >> 2) << 5)) -#define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) +# define OFFSET12_B(offset) (offset << 10) +# define OFFSET12_H(offset) ((offset >> 1) << 10) +# define OFFSET12_W(offset) ((offset >> 2) << 10) +# define OFFSET12_Q(offset) ((offset >> 3) << 10) -#define OFFSET12_B(offset) (offset << 10) -#define OFFSET12_H(offset) ((offset >> 1) << 10) -#define OFFSET12_W(offset) ((offset >> 2) << 10) -#define OFFSET12_Q(offset) ((offset >> 3) << 10) +# define SHIFT_IMM_V4H(shift) (((shift) | 0x10) << 16) +# define SHIFT_IMM_V2S(shift) (((shift) | 0x20) << 16) +# define SHIFT_IMM_V2D(shift) (((shift) | 0x40) << 16) -#define SHIFT_IMM_V4H(shift) (((shift) | 0x10) << 16) -#define SHIFT_IMM_V2S(shift) (((shift) | 0x20) << 16) -#define SHIFT_IMM_V2D(shift) (((shift) | 0x40) << 16) +# define SHRN_SHIFT_IMM_V4S(shift) (((shift) | 0x10) << 16) -#define SHRN_SHIFT_IMM_V4S(shift) (((shift) | 0x10) << 16) - -#define DUP_ELEMENT(element) ((element) << 19) +# define DUP_ELEMENT(element) ((element) << 19) /*Returns true if offset fits into 19 bits*/ -static int offset_is_19bit(int offset) +static int +offset_is_19bit(int offset) { - if (offset >= (1 << (18+2))) - return 0; - if (offset < -(1 << (18+2))) - return 0; - return 1; + if (offset >= (1 << (18 + 2))) + return 0; + if (offset < -(1 << (18 + 2))) + return 0; + return 1; } /*Returns true if offset fits into 26 bits*/ -static int offset_is_26bit(int offset) +static int +offset_is_26bit(int offset) { - if (offset >= (1 << (25+2))) - return 0; - if (offset < -(1 << (25+2))) - return 0; - return 1; + if (offset >= (1 << (25 + 2))) + return 0; + if (offset < -(1 << (25 + 2))) + return 0; + return 1; } -static inline int imm_is_imm16(uint32_t imm_data) +static inline int +imm_is_imm16(uint32_t imm_data) { - if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) - return 1; - return 0; + if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) + return 1; + return 0; } static void codegen_allocate_new_block(codeblock_t *block); -static inline void codegen_addlong(codeblock_t *block, uint32_t val) +static inline void +codegen_addlong(codeblock_t *block, uint32_t val) { - if (block_pos >= (BLOCK_MAX-4)) - codegen_allocate_new_block(block); - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; + if (block_pos >= (BLOCK_MAX - 4)) + codegen_allocate_new_block(block); + *(uint32_t *) &block_write_data[block_pos] = val; + block_pos += 4; } -static void codegen_allocate_new_block(codeblock_t *block) +static void +codegen_allocate_new_block(codeblock_t *block) { - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - uint32_t offset = (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]; + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + uint32_t offset = (uintptr_t) new_ptr - (uintptr_t) &block_write_data[block_pos]; - if (!offset_is_26bit(offset)) - fatal("codegen_allocate_new_block - offset out of range %x\n", offset); - /*Add a jump instruction to the new block*/ - *(uint32_t *)&block_write_data[block_pos] = OPCODE_B | OFFSET26(offset); + if (!offset_is_26bit(offset)) + fatal("codegen_allocate_new_block - offset out of range %x\n", offset); + /*Add a jump instruction to the new block*/ + *(uint32_t *) &block_write_data[block_pos] = OPCODE_B | OFFSET26(offset); - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; } -void codegen_alloc(codeblock_t *block, int size) +void +codegen_alloc(codeblock_t *block, int size) { - if (block_pos >= (BLOCK_MAX-size)) - codegen_allocate_new_block(block); + if (block_pos >= (BLOCK_MAX - size)) + codegen_allocate_new_block(block); } -void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (!imm_data) - host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); - else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) - { - host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xff000000)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - { - host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); - codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t) imm_data < 0 && imm_data != 0x80000000) { + host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t) imm_data); + } else if (!(imm_data & 0xff000000)) { + if (imm_data & 0xfff) { + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm_data) +void +host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm_data) { - if (!(imm_data & ~0xffffffull)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - fatal("ADD_IMM_X %016llx\n", imm_data); + if (!(imm_data & ~0xffffffull)) { + if (imm_data & 0xfff) { + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else + fatal("ADD_IMM_X %016llx\n", imm_data); } -void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADDP_V4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ADDP_V4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADDP_V4S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ADDP_V4S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) +void +host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) { - codegen_addlong(block, OPCODE_ADR | Rd(dst_reg) | OFFSET20(offset)); + codegen_addlong(block, OPCODE_ADR | Rd(dst_reg) | OFFSET20(offset)); } -void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - uint32_t imm_encoding = host_arm64_find_imm(imm_data); + uint32_t imm_encoding = host_arm64_find_imm(imm_data); - if (imm_encoding) - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (imm_encoding) { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_AND_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_AND_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - uint32_t imm_encoding = host_arm64_find_imm(imm_data); + uint32_t imm_encoding = host_arm64_find_imm(imm_data); - if (imm_encoding) - { - codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_ANDS_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (imm_encoding) { + codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ANDS_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +void +host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { - codegen_addlong(block, OPCODE_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); + codegen_addlong(block, OPCODE_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_B(codeblock_t *block, void *dest) +void +host_arm64_B(codeblock_t *block, void *dest) { - int offset; + int offset; - codegen_alloc(block, 4); - offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; + codegen_alloc(block, 4); + offset = (uintptr_t) dest - (uintptr_t) &block_write_data[block_pos]; - if (!offset_is_26bit(offset)) - fatal("host_arm64_B - offset out of range %x\n", offset); - codegen_addlong(block, OPCODE_B | OFFSET26(offset)); + if (!offset_is_26bit(offset)) + fatal("host_arm64_B - offset out of range %x\n", offset); + codegen_addlong(block, OPCODE_B | OFFSET26(offset)); } -void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +void +host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { - codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width-1) & 31)); + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width - 1) & 31)); } -void host_arm64_BLR(codeblock_t *block, int addr_reg) +void +host_arm64_BLR(codeblock_t *block, int addr_reg) { - codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); + codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); } -uint32_t *host_arm64_BCC_(codeblock_t *block) +uint32_t * +host_arm64_BCC_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_CS | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_CS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BCS_(codeblock_t *block) +uint32_t * +host_arm64_BCS_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_CC | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_CC | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BEQ_(codeblock_t *block) +uint32_t * +host_arm64_BEQ_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_NE | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_NE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BGE_(codeblock_t *block) +uint32_t * +host_arm64_BGE_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_LT | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LT | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BGT_(codeblock_t *block) +uint32_t * +host_arm64_BGT_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_LE | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BHI_(codeblock_t *block) +uint32_t * +host_arm64_BHI_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_LS | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BLE_(codeblock_t *block) +uint32_t * +host_arm64_BLE_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_GT | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_GT | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BLS_(codeblock_t *block) +uint32_t * +host_arm64_BLS_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_HI | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_HI | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BLT_(codeblock_t *block) +uint32_t * +host_arm64_BLT_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_GE | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_GE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BMI_(codeblock_t *block) +uint32_t * +host_arm64_BMI_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_PL | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_PL | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BNE_(codeblock_t *block) +uint32_t * +host_arm64_BNE_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_EQ | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_EQ | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BPL_(codeblock_t *block) +uint32_t * +host_arm64_BPL_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_MI | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_MI | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BVC_(codeblock_t *block) +uint32_t * +host_arm64_BVC_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_VS | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_VS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BVS_(codeblock_t *block) +uint32_t * +host_arm64_BVS_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_VC | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_VC | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -void host_arm64_branch_set_offset(uint32_t *opcode, void *dest) +void +host_arm64_branch_set_offset(uint32_t *opcode, void *dest) { - int offset = (uintptr_t)dest - (uintptr_t)opcode; - *opcode |= OFFSET26(offset); + int offset = (uintptr_t) dest - (uintptr_t) opcode; + *opcode |= OFFSET26(offset); } -void host_arm64_BR(codeblock_t *block, int addr_reg) +void +host_arm64_BR(codeblock_t *block, int addr_reg) { - codegen_addlong(block, OPCODE_BR | Rn(addr_reg)); + codegen_addlong(block, OPCODE_BR | Rn(addr_reg)); } -void host_arm64_BEQ(codeblock_t *block, void *dest) +void +host_arm64_BEQ(codeblock_t *block, void *dest) { - uint32_t *opcode = host_arm64_BEQ_(block); - host_arm64_branch_set_offset(opcode, dest); + uint32_t *opcode = host_arm64_BEQ_(block); + host_arm64_branch_set_offset(opcode, dest); } -void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_BIC_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_BIC_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) +void +host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) { - int offset; + int offset; - codegen_alloc(block, 4); - offset = dest - (uintptr_t)&block_write_data[block_pos]; - if (offset_is_19bit(offset)) - { - codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); - } - else - { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_CBZ | OFFSET19(8) | Rt(reg)); - offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; - codegen_addlong(block, OPCODE_B | OFFSET26(offset)); - } + codegen_alloc(block, 4); + offset = dest - (uintptr_t) &block_write_data[block_pos]; + if (offset_is_19bit(offset)) { + codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); + } else { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_CBZ | OFFSET19(8) | Rt(reg)); + offset = (uintptr_t) dest - (uintptr_t) &block_write_data[block_pos]; + codegen_addlong(block, OPCODE_B | OFFSET26(offset)); + } } -void host_arm64_CMEQ_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMEQ_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMEQ_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMEQ_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMEQ_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMEQ_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMEQ_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMEQ_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMGT_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMGT_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMGT_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMGT_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMGT_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMGT_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMGT_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMGT_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) +void +host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) { - if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) - { - host_arm64_CMP_IMM(block, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xfffff000)) - { - codegen_addlong(block, OPCODE_CMN_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMN_IMM %08x\n", imm_data); + if ((int32_t) imm_data < 0 && imm_data != (1ull << 31)) { + host_arm64_CMP_IMM(block, src_n_reg, -(int32_t) imm_data); + } else if (!(imm_data & 0xfffff000)) { + codegen_addlong(block, OPCODE_CMN_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMN_IMM %08x\n", imm_data); } -void host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) +void +host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) { - if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) - { - host_arm64_CMPX_IMM(block, src_n_reg, -(int64_t)imm_data); - } - else if (!(imm_data & 0xfffffffffffff000ull)) - { - codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMNX_IMM %08x\n", imm_data); + if ((int64_t) imm_data < 0 && imm_data != (1ull << 63)) { + host_arm64_CMPX_IMM(block, src_n_reg, -(int64_t) imm_data); + } else if (!(imm_data & 0xfffffffffffff000ull)) { + codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMNX_IMM %08x\n", imm_data); } -void host_arm64_CMP_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) +void +host_arm64_CMP_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) { - if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) - { - host_arm64_CMN_IMM(block, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xfffff000)) - { - codegen_addlong(block, OPCODE_CMP_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMP_IMM %08x\n", imm_data); + if ((int32_t) imm_data < 0 && imm_data != (1ull << 31)) { + host_arm64_CMN_IMM(block, src_n_reg, -(int32_t) imm_data); + } else if (!(imm_data & 0xfffff000)) { + codegen_addlong(block, OPCODE_CMP_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMP_IMM %08x\n", imm_data); } -void host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) +void +host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) { - if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) - { - host_arm64_CMNX_IMM(block, src_n_reg, -(int64_t)imm_data); - } - else if (!(imm_data & 0xfffffffffffff000ull)) - { - codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMPX_IMM %08x\n", imm_data); + if ((int64_t) imm_data < 0 && imm_data != (1ull << 63)) { + host_arm64_CMNX_IMM(block, src_n_reg, -(int64_t) imm_data); + } else if (!(imm_data & 0xfffffffffffff000ull)) { + codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMPX_IMM %08x\n", imm_data); } -void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_CSEL_CC(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CSEL_CC(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_CC) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_CC) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_EQ) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_EQ) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_VS) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_VS) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) +void +host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) { - codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); + codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); } -void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - uint32_t imm_encoding = host_arm64_find_imm(imm_data); + uint32_t imm_encoding = host_arm64_find_imm(imm_data); - if (imm_encoding) - { - codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (imm_encoding) { + codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FABS_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FABS_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FCMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FCMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FCMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCMGE_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FCMGE_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FCMGE_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FCMGE_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FCMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FCMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FCMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg) +void +host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FCMP_D | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FCMP_D | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVT_D_S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVT_D_S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVT_S_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVT_S_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTMS_W_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTMS_W_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTMS_W_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTMS_W_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTMS_X_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTMS_X_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTMS_X_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTMS_X_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTNS_W_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTNS_W_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTNS_W_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTNS_W_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTNS_X_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTNS_X_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTNS_X_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTNS_X_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTPS_W_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTPS_W_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTPS_W_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTPS_W_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTPS_X_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTPS_X_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTPS_X_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTPS_X_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTZS_W_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTZS_W_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTZS_W_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTZS_W_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTZS_X_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTZS_X_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTZS_V2S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTZS_V2S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTZS_V2S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTZS_V2S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FDIV_S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FDIV_S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FDIV_S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FDIV_S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMAX_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FMAX_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FMAX_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FMAX_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMIN_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FMIN_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FMIN_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FMIN_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FMUL_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FMUL_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMUL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FMUL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FMUL_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FMUL_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FSUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FSUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FSUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FSUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_D_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_D_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_D_Q | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_D_Q | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_Q_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_Q_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_S_W | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_S_W | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_S_ONE(codeblock_t *block, int dst_reg) +void +host_arm64_FMOV_S_ONE(codeblock_t *block, int dst_reg) { - codegen_addlong(block, OPCODE_FMOV_S_ONE | Rd(dst_reg)); + codegen_addlong(block, OPCODE_FMOV_S_ONE | Rd(dst_reg)); } -void host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FNEG_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FNEG_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FRINTX_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FRINTX_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FSQRT_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FSQRT_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FSQRT_S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FSQRT_S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FSQRT_S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FSQRT_S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) +void +host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { - if (!in_range7_x(offset)) - fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset); - codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); + if (!in_range7_x(offset)) + fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); } -void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_w(offset)) - fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_w(offset)) + fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_q(offset)) - fatal("host_arm64_LDR_IMM_X out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDR_IMM_X | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_q(offset)) + fatal("host_arm64_LDR_IMM_X out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDR_IMM_X | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_X(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG_X(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDRX_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDRX_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset) { - codegen_addlong(block, OPCODE_LDR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_b(offset)) - fatal("host_arm64_LDRB_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDRB_IMM_W | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_b(offset)) + fatal("host_arm64_LDRB_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDRB_IMM_W | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_h(offset)) - fatal("host_arm64_LDRH_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_h(offset)) + fatal("host_arm64_LDRH_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDRX_REG_LSL3 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDRX_REG_LSL3 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +void +host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { - codegen_addlong(block, OPCODE_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); + codegen_addlong(block, OPCODE_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +void +host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { - codegen_addlong(block, OPCODE_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); + codegen_addlong(block, OPCODE_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_ASR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ORR_ASR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - if (dst_reg != src_m_reg || shift) - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + if (dst_reg != src_m_reg || shift) + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_ROR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ORR_ROR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data) +void +host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data) { - codegen_addlong(block, OPCODE_MOVZ_X | MOV_WIDE_HW(0) | IMM16(imm_data & 0xffff) | Rd(reg)); - if ((imm_data >> 16) & 0xffff) - codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(1) | IMM16((imm_data >> 16) & 0xffff) | Rd(reg)); - if ((imm_data >> 32) & 0xffff) - codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(2) | IMM16((imm_data >> 32) & 0xffff) | Rd(reg)); - if ((imm_data >> 48) & 0xffff) - codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(3) | IMM16((imm_data >> 48) & 0xffff) | Rd(reg)); + codegen_addlong(block, OPCODE_MOVZ_X | MOV_WIDE_HW(0) | IMM16(imm_data & 0xffff) | Rd(reg)); + if ((imm_data >> 16) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(1) | IMM16((imm_data >> 16) & 0xffff) | Rd(reg)); + if ((imm_data >> 32) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(2) | IMM16((imm_data >> 32) & 0xffff) | Rd(reg)); + if ((imm_data >> 48) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(3) | IMM16((imm_data >> 48) & 0xffff) | Rd(reg)); } -void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - if (dst_reg != src_m_reg) - codegen_addlong(block, OPCODE_ORRX_LSL | Rd(dst_reg) | Rn(REG_XZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + if (dst_reg != src_m_reg) + codegen_addlong(block, OPCODE_ORRX_LSL | Rd(dst_reg) | Rn(REG_XZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) +void +host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) { - int hw; + int hw; - if (!imm_is_imm16(imm_data)) - fatal("MOVZ_IMM - imm not representable %08x\n", imm_data); + if (!imm_is_imm16(imm_data)) + fatal("MOVZ_IMM - imm not representable %08x\n", imm_data); - hw = (imm_data & 0xffff0000) ? 1 : 0; - if (hw) - imm_data >>= 16; + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; - codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); + codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); } -void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) +void +host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) { - int hw; + int hw; - if (!imm_is_imm16(imm_data)) - fatal("MOVK_IMM - imm not representable %08x\n", imm_data); + if (!imm_is_imm16(imm_data)) + fatal("MOVK_IMM - imm not representable %08x\n", imm_data); - hw = (imm_data & 0xffff0000) ? 1 : 0; - if (hw) - imm_data >>= 16; + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; - codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); + codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); } -void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg) +void +host_arm64_MSR_FPCR(codeblock_t *block, int src_reg) { - codegen_addlong(block, OPCODE_MSR_FPCR | Rd(src_reg)); + codegen_addlong(block, OPCODE_MSR_FPCR | Rd(src_reg)); } -void host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_MUL_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_MUL_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_NOP(codeblock_t *block) +void +host_arm64_NOP(codeblock_t *block) { - codegen_addlong(block, OPCODE_NOP); + codegen_addlong(block, OPCODE_NOP); } -void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - uint32_t imm_encoding = host_arm64_find_imm(imm_data); + uint32_t imm_encoding = host_arm64_find_imm(imm_data); - if (imm_encoding) - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (imm_encoding) { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ORR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ORR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_RET(codeblock_t *block, int reg) +void +host_arm64_RET(codeblock_t *block, int reg) { - codegen_addlong(block, OPCODE_RET | Rn(reg)); + codegen_addlong(block, OPCODE_RET | Rn(reg)); } -void host_arm64_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +void +host_arm64_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { - codegen_addlong(block, OPCODE_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); + codegen_addlong(block, OPCODE_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg) +void +host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg) { - codegen_addlong(block, OPCODE_SADDLP_V2S_4H | Rd(dst_reg) | Rn(src_n_reg)); + codegen_addlong(block, OPCODE_SADDLP_V2S_4H | Rd(dst_reg) | Rn(src_n_reg)); } -void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +void +host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { - codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); + codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb + width - 1) & 31)); } -void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SCVTF_D_Q | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SCVTF_D_Q | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SCVTF_V2S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SCVTF_V2S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SCVTF_V2S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SCVTF_V2S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 16) - fatal("host_arm64_SHRN_V4H_4S : shift > 16\n"); - codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | SHRN_SHIFT_IMM_V4S(16-shift)); + if (shift > 16) + fatal("host_arm64_SHRN_V4H_4S : shift > 16\n"); + codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | SHRN_SHIFT_IMM_V4S(16 - shift)); } -void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SMULL_V4S_4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SMULL_V4S_4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); + codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); } -void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); + codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); } -void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SHL_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); + codegen_addlong(block, OPCODE_SHL_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); } -void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 16) - fatal("host_arm_USHR_V4H : shift > 16\n"); - codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16-shift)); + if (shift > 16) + fatal("host_arm_USHR_V4H : shift > 16\n"); + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16 - shift)); } -void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 32) - fatal("host_arm_SSHR_V2S : shift > 32\n"); - codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32-shift)); + if (shift > 32) + fatal("host_arm_SSHR_V2S : shift > 32\n"); + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32 - shift)); } -void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 64) - fatal("host_arm_SSHR_V2D : shift > 64\n"); - codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64-shift)); + if (shift > 64) + fatal("host_arm_SSHR_V2D : shift > 64\n"); + codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64 - shift)); } -void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) +void +host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { - if (!in_range7_x(offset)) - fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset); - codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); + if (!in_range7_x(offset)) + fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); } -void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_w(offset)) - fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_w(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_q(offset)) - fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STR_IMM_Q | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_q(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_Q | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset) +void +host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset) { - codegen_addlong(block, OPCODE_STR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(src_reg)); } -void host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_b(offset)) - fatal("host_arm64_STRB_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_b(offset)) + fatal("host_arm64_STRB_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_h(offset)) - fatal("host_arm64_STRH_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_h(offset)) + fatal("host_arm64_STRH_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (!imm_data) - host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); - else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) - { - host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xff000000)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - { - host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); - codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t) imm_data < 0 && imm_data != 0x80000000) { + host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t) imm_data); + } else if (!(imm_data & 0xff000000)) { + if (imm_data & 0xfff) { + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit) +uint32_t * +host_arm64_TBNZ(codeblock_t *block, int reg, int bit) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_TBZ | Rt(reg) | BIT_TBxZ(bit) | OFFSET14(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_TBZ | Rt(reg) | BIT_TBxZ(bit) | OFFSET14(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +void +host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { - codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); + codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb + width - 1) & 31)); } -void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_UQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_UQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_UQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_UQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_UQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_UQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_UQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_UQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_UQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 16) - fatal("host_arm_USHR_V4H : shift > 16\n"); - codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16-shift)); + if (shift > 16) + fatal("host_arm_USHR_V4H : shift > 16\n"); + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16 - shift)); } -void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 32) - fatal("host_arm_USHR_V4S : shift > 32\n"); - codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32-shift)); + if (shift > 32) + fatal("host_arm_USHR_V4S : shift > 32\n"); + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32 - shift)); } -void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 64) - fatal("host_arm_USHR_V2D : shift > 64\n"); - codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64-shift)); + if (shift > 64) + fatal("host_arm_USHR_V2D : shift > 64\n"); + codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64 - shift)); } -void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP1_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP1_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP1_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP1_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP2_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP2_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP2_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP2_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_call(codeblock_t *block, void *dst_addr) +void +host_arm64_call(codeblock_t *block, void *dst_addr) { - host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); - host_arm64_BLR(block, REG_X16); + host_arm64_MOVX_IMM(block, REG_X16, (uint64_t) dst_addr); + host_arm64_BLR(block, REG_X16); } -void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr) +void +host_arm64_jump(codeblock_t *block, uintptr_t dst_addr) { - host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); - host_arm64_BR(block, REG_X16); + host_arm64_MOVX_IMM(block, REG_X16, (uint64_t) dst_addr); + host_arm64_BR(block, REG_X16); } -void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) +void +host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) { - if (imm_is_imm16(imm_data)) - host_arm64_MOVZ_IMM(block, reg, imm_data); - else - { - host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000); - } + if (imm_is_imm16(imm_data)) + host_arm64_MOVZ_IMM(block, reg, imm_data); + else { + host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000); + } } #endif diff --git a/src/codegen_new/codegen_backend_arm64_ops.h b/src/codegen_new/codegen_backend_arm64_ops.h index c89a02311..df751b4aa 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.h +++ b/src/codegen_new/codegen_backend_arm64_ops.h @@ -251,13 +251,11 @@ void host_arm64_call(codeblock_t *block, void *dst_addr); void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr); void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); - -#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7)) +#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) &7)) #define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000)) -#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset) & 1)) -#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3)) -#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7)) - +#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset) &1)) +#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) &3)) +#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) &7)) void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 10a07a4a2..91fb9c903 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -1,3372 +1,3251 @@ #if defined __aarch64__ || defined _M_ARM64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "x86.h" -#include "x87.h" -#include "386_common.h" -#include "codegen.h" -#include "codegen_backend.h" -#include "codegen_backend_arm64_defs.h" -#include "codegen_backend_arm64_ops.h" -#include "codegen_ir_defs.h" +# include "x86.h" +# include "x87.h" +# include "386_common.h" +# include "codegen.h" +# include "codegen_backend.h" +# include "codegen_backend_arm64_defs.h" +# include "codegen_backend_arm64_ops.h" +# include "codegen_ir_defs.h" -#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) +# define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) -#define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0x1f) +# define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0x1f) -#define REG_IS_L(size) (size == IREG_SIZE_L) -#define REG_IS_W(size) (size == IREG_SIZE_W) -#define REG_IS_B(size) (size == IREG_SIZE_B) -#define REG_IS_BH(size) (size == IREG_SIZE_BH) -#define REG_IS_D(size) (size == IREG_SIZE_D) -#define REG_IS_Q(size) (size == IREG_SIZE_Q) +# define REG_IS_L(size) (size == IREG_SIZE_L) +# define REG_IS_W(size) (size == IREG_SIZE_W) +# define REG_IS_B(size) (size == IREG_SIZE_B) +# define REG_IS_BH(size) (size == IREG_SIZE_BH) +# define REG_IS_D(size) (size == IREG_SIZE_D) +# define REG_IS_Q(size) (size == IREG_SIZE_Q) -static int codegen_ADD(codeblock_t *block, uop_t *uop) +static int +codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_ADD_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_a, 0x0000ff00); - host_arm64_ADD_REG(block, REG_TEMP, REG_TEMP, src_reg_b, 0); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_ADD_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_a, 0x0000ff00); + host_arm64_ADD_REG(block, REG_TEMP, REG_TEMP, src_reg_b, 0); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ADD_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ADD_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { - host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); - return 0; + host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + return 0; } -static int codegen_AND(codeblock_t *block, uop_t *uop) +static int +codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_AND_REG_V(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_AND_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff0000); - host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); - host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); - host_arm64_AND_REG_ASR(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); - host_arm64_AND_REG_ROR(block, dest_reg, src_reg_a, REG_TEMP, 24); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); - host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); - host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_a, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_a, 0xffff00ff); - host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_b, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_AND_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_AND_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff0000); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG_ASR(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); + host_arm64_AND_REG_ROR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_a, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_a, 0xffff00ff); + host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_b, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); - } - else - fatal("AND_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); + } else + fatal("AND_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ANDN(codeblock_t *block, uop_t *uop) +static int +codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_BIC_REG_V(block, dest_reg, src_reg_b, src_reg_a); - } - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_BIC_REG_V(block, dest_reg, src_reg_b, src_reg_a); + } else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { - host_arm64_call(block, uop->p); + host_arm64_call(block, uop->p); - return 0; + return 0; } -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); - host_arm64_call(block, uop->p); - host_arm64_MOV_REG(block, dest_reg, REG_W0, 0); + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_arm64_call(block, uop->p); + host_arm64_MOV_REG(block, dest_reg, REG_W0, 0); - return 0; + return 0; } -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { - host_arm64_call(block, uop->p); - host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); + host_arm64_call(block, uop->p); + host_arm64_CBNZ(block, REG_X0, (uintptr_t) codegen_exit_rout); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_CMP_IMM(block, src_reg, uop->imm_data); - } - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); - host_arm64_BEQ(block, uop->p); + if (REG_IS_L(src_size)) { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_arm64_BEQ(block, uop->p); - return 0; + return 0; } -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BNE_(block); + uop->p = host_arm64_BNE_(block); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BEQ_(block); + uop->p = host_arm64_BEQ_(block); - return 0; + return 0; } -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); - jump_p = host_arm64_BCC_(block); - host_arm64_branch_set_offset(jump_p, uop->p); + jump_p = host_arm64_BCC_(block); + host_arm64_branch_set_offset(jump_p, uop->p); - return 0; + return 0; } -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); - jump_p = host_arm64_BHI_(block); - host_arm64_branch_set_offset(jump_p, uop->p); + jump_p = host_arm64_BHI_(block); + host_arm64_branch_set_offset(jump_p, uop->p); - return 0; + return 0; } -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BCS_(block); + uop->p = host_arm64_BCS_(block); - return 0; + return 0; } -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BHI_(block); + uop->p = host_arm64_BHI_(block); - return 0; + return 0; } -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BGE_(block); + uop->p = host_arm64_BGE_(block); - return 0; + return 0; } -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BGT_(block); + uop->p = host_arm64_BGT_(block); - return 0; + return 0; } -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BVC_(block); + uop->p = host_arm64_BVC_(block); - return 0; + return 0; } -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BNE_(block); + uop->p = host_arm64_BNE_(block); - return 0; + return 0; } -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BCC_(block); + uop->p = host_arm64_BCC_(block); - return 0; + return 0; } -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BLS_(block); + uop->p = host_arm64_BLS_(block); - return 0; + return 0; } -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BLT_(block); + uop->p = host_arm64_BLT_(block); - return 0; + return 0; } -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BLE_(block); + uop->p = host_arm64_BLE_(block); - return 0; + return 0; } -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BVS_(block); + uop->p = host_arm64_BVS_(block); - return 0; + return 0; } -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BEQ_(block); + uop->p = host_arm64_BEQ_(block); - return 0; + return 0; } -static int codegen_FABS(codeblock_t *block, uop_t *uop) +static int +codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FABS_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FABS_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_FCHS(codeblock_t *block, uop_t *uop) +static int +codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FNEG_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FNEG_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +static int +codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FSQRT_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FSQRT_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_FTST(codeblock_t *block, uop_t *uop) +static int +codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP); - host_arm64_MOVZ_IMM(block, dest_reg, 0); - host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); - host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); - host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0|C2|C3); - host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); - host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); - } - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP); + host_arm64_MOVZ_IMM(block, dest_reg, 0); + host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3); + host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); + host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); + } else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FADD(codeblock_t *block, uop_t *uop) +static int +codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FADD_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FADD_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FCOM(codeblock_t *block, uop_t *uop) +static int +codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_MOVZ_IMM(block, dest_reg, 0); - host_arm64_FCMP_D(block, src_reg_a, src_reg_b); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); - host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); - host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0|C2|C3); - host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); - host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); - } - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_MOVZ_IMM(block, dest_reg, 0); + host_arm64_FCMP_D(block, src_reg_a, src_reg_b); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3); + host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); + host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); + } else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FDIV(codeblock_t *block, uop_t *uop) +static int +codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FDIV_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FDIV_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FMUL(codeblock_t *block, uop_t *uop) +static int +codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FMUL_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FMUL_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FSUB(codeblock_t *block, uop_t *uop) +static int +codegen_FSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FSUB_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FSUB_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +static int +codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_ptr; + uint32_t *branch_ptr; - if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) - fatal("codegen_FP_ENTER - out of range\n"); + if (!in_range12_w((uintptr_t) &cr0 - (uintptr_t) &cpu_state)) + fatal("codegen_FP_ENTER - out of range\n"); - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm64_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm64_BEQ_(block); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cr0 - (uintptr_t) &cpu_state); + host_arm64_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm64_BEQ_(block); - host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm64_mov_imm(block, REG_ARG0, 7); - host_arm64_call(block, x86_int); - host_arm64_B(block, codegen_exit_rout); + host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.oldpc - (uintptr_t) &cpu_state); + host_arm64_mov_imm(block, REG_ARG0, 7); + host_arm64_call(block, x86_int); + host_arm64_B(block, codegen_exit_rout); - host_arm64_branch_set_offset(branch_ptr, &block_write_data[block_pos]); + host_arm64_branch_set_offset(branch_ptr, &block_write_data[block_pos]); - return 0; + return 0; } -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +static int +codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_ptr; + uint32_t *branch_ptr; - if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) - fatal("codegen_MMX_ENTER - out of range\n"); + if (!in_range12_w((uintptr_t) &cr0 - (uintptr_t) &cpu_state)) + fatal("codegen_MMX_ENTER - out of range\n"); - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm64_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm64_BEQ_(block); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cr0 - (uintptr_t) &cpu_state); + host_arm64_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm64_BEQ_(block); - host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm64_mov_imm(block, REG_ARG0, 7); - host_arm64_call(block, x86_int); - host_arm64_B(block, codegen_exit_rout); + host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.oldpc - (uintptr_t) &cpu_state); + host_arm64_mov_imm(block, REG_ARG0, 7); + host_arm64_call(block, x86_int); + host_arm64_B(block, codegen_exit_rout); - host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); + host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); - host_arm64_mov_imm(block, REG_TEMP, 0x01010101); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); - host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); + host_arm64_mov_imm(block, REG_TEMP, 0x01010101); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[0] - (uintptr_t) &cpu_state); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[4] - (uintptr_t) &cpu_state); + host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); + host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); - return 0; + return 0; } -static int codegen_JMP(codeblock_t *block, uop_t *uop) +static int +codegen_JMP(codeblock_t *block, uop_t *uop) { - host_arm64_jump(block, (uintptr_t)uop->p); + host_arm64_jump(block, (uintptr_t) uop->p); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); - } - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); + } else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) { - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); - return 0; + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; } -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) { - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); - return 0; + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; } -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) { - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); - return 0; + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; } -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); - return 0; + return 0; } -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); - host_arm64_MOVX_IMM(block, REG_ARG1, (uint64_t)uop->p); - host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); - host_arm64_call(block, (void *)loadseg); - host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); + host_arm64_MOVX_IMM(block, REG_ARG1, (uint64_t) uop->p); + host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); + host_arm64_call(block, (void *) loadseg); + host_arm64_CBNZ(block, REG_X0, (uintptr_t) codegen_exit_rout); - return 0; + return 0; } -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - host_arm64_ADD_IMM(block, REG_X0, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm64_call(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_call(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_call(block, codegen_mem_load_long); - } - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); - } + host_arm64_ADD_IMM(block, REG_X0, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm64_call(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm64_call(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm64_call(block, codegen_mem_load_long); + } else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); + } - return 0; + return 0; } -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm64_call(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_call(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_call(block, codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_arm64_call(block, codegen_mem_load_quad); - } - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); - } - else if (REG_IS_Q(dest_size)) - { - host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); - } + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm64_call(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm64_call(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm64_call(block, codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_arm64_call(block, codegen_mem_load_quad); + } else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); + } else if (REG_IS_Q(dest_size)) { + host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); + } - return 0; + return 0; } -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_call(block, codegen_mem_load_double); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_call(block, codegen_mem_load_double); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); - return 0; + return 0; } -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_call(block, codegen_mem_load_single); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - host_arm64_FCVT_D_S(block, dest_reg, REG_V_TEMP); + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_call(block, codegen_mem_load_single); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + host_arm64_FCVT_D_S(block, dest_reg, REG_V_TEMP); - return 0; + return 0; } -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - host_arm64_ADD_IMM(block, REG_W0, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); - host_arm64_call(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, REG_W1, src_reg, 0); - host_arm64_call(block, codegen_mem_store_long); - } - else - fatal("MEM_STORE_ABS - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); - host_arm64_call(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, REG_W1, src_reg, 0); - host_arm64_call(block, codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_mem_store_quad); - } - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_ADD_IMM(block, REG_W0, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); host_arm64_call(block, codegen_mem_store_byte); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - host_arm64_mov_imm(block, REG_W1, uop->imm_data); + } else if (REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); host_arm64_call(block, codegen_mem_store_word); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - host_arm64_mov_imm(block, REG_W1, uop->imm_data); + } else if (REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, REG_W1, src_reg, 0); host_arm64_call(block, codegen_mem_store_long); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + } else + fatal("MEM_STORE_ABS - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); - return 0; + return 0; +} +static int +codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); + host_arm64_call(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, REG_W1, src_reg, 0); + host_arm64_call(block, codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_quad); + } else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + + return 0; } -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_byte); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_FCVT_S_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_mem_store_single); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; + return 0; } -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_word); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_mem_store_double); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + return 0; +} +static int +codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - return 0; + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_long); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + + return 0; } -static int codegen_MOV(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_BFI(block, dest_reg, src_reg, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_BFI(block, dest_reg, src_reg, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) - { - host_arm64_BFI(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - } - else - fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - return 0; + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_FCVT_S_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_single); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + + return 0; } -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (REG_IS_L(dest_size)) - { - host_arm64_mov_imm(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data & 0xffff); - } - else if (REG_IS_B(dest_size)) - { - host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("MOV_IMM %x\n", uop->dest_reg_a_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_arm64_MOVX_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_double); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); - return 0; + return 0; } -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) +static int +codegen_MOV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm64_SBFX(block, dest_reg, src_reg, 0, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SBFX(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm64_SBFX(block, dest_reg, src_reg, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_BFI(block, dest_reg, src_reg, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_BFI(block, dest_reg, src_reg, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) { + host_arm64_BFI(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + } else + fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) +static int +codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_arm64_FMOV_D_Q(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_arm64_FMOV_W_S(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, 0xffff); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size)) { + host_arm64_mov_imm(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data & 0xffff); + } else if (REG_IS_B(dest_size)) { + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("MOV_IMM %x\n", uop->dest_reg_a_real); - return 0; + return 0; +} +static int +codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + host_arm64_MOVX_IMM(block, uop->dest_reg_a_real, (uint64_t) uop->p); + + return 0; } -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +static int +codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_arm64_SCVTF_D_W(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - host_arm64_FMOV_Q_D(block, REG_TEMP, src_reg); - host_arm64_SCVTF_D_Q(block, dest_reg, REG_TEMP); - } + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm64_SBFX(block, dest_reg, src_reg, 0, 8); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SBFX(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm64_SBFX(block, dest_reg, src_reg, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_arm64_FMOV_D_Q(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_arm64_FMOV_W_S(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, 0xffff); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int +codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_arm64_SCVTF_D_W(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + host_arm64_FMOV_Q_D(block, REG_TEMP, src_reg); + host_arm64_SCVTF_D_Q(block, dest_reg, REG_TEMP); + } else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round); + host_arm64_MOV_REG(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_arm64_FMOV_D_D(block, dest_reg, src_64_reg); + branch_offset = host_arm64_TBNZ(block, tag_reg, 7); + + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round_quad); + host_arm64_FMOV_D_Q(block, dest_reg, REG_TEMP); + + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); + } else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm64_LDR_IMM_W(block, dest_reg, REG_TEMP, 0); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm64_LDRB_IMM_W(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size)) { + host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm64_LDRH_IMM(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm64_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int +codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + +static int +codegen_OR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ORR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_ORR_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("OR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int +codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMEQ_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm64_FCVTZS_V2S(block, dest_reg, src_reg_a); + } else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRECPE/VRECPS)*/ + host_arm64_FMOV_S_ONE(block, REG_V_TEMP); + host_arm64_FDIV_S(block, dest_reg, REG_V_TEMP, src_reg_a); + host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); + } else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ + host_arm64_FSQRT_S(block, REG_V_TEMP, src_reg_a); + host_arm64_FMOV_S_ONE(block, REG_V_TEMP); + host_arm64_FDIV_S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); + } else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm64_SCVTF_V2S(block, dest_reg, src_reg_a); + } else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int +codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SMULL_V4S_4H(block, REG_V_TEMP, src_reg_a, src_reg_b); + host_arm64_ADDP_V4S(block, dest_reg, REG_V_TEMP, REG_V_TEMP); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_SHRN_V4H_4S(block, dest_reg, dest_reg, 16); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm64_SHL_V4H(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_fp_round); - host_arm64_MOV_REG(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_fp_round); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm64_SHL_V2S(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +static int +codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_arm64_FMOV_D_D(block, dest_reg, src_64_reg); - branch_offset = host_arm64_TBNZ(block, tag_reg, 7); - - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_fp_round_quad); - host_arm64_FMOV_D_Q(block, dest_reg, REG_TEMP); - - host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm64_SHL_V2D(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm64_LDR_IMM_W(block, dest_reg, REG_TEMP, 0); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm64_SSHR_V4H(block, dest_reg, src_reg, 15); else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + host_arm64_SSHR_V4H(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm64_LDRB_IMM_W(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size)) - { - host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm64_SSHR_V2S(block, dest_reg, src_reg, 31); else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + host_arm64_SSHR_V2S(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm64_LDRH_IMM(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm64_SSHR_V2D(block, dest_reg, src_reg, 63); else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + host_arm64_SSHR_V2D(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } - -static int codegen_NOP(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { - return 0; -} + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); -static int codegen_OR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ORR_REG_V(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_ORR_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("OR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + host_arm64_USHR_V4H(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + host_arm64_USHR_V2S(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + host_arm64_USHR_V2D(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PADDB(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ADD_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDW(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ADD_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDD(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ADD_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SUB_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMEQ_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) +static int +codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm64_FCVTZS_V2S(block, dest_reg, src_reg_a); - } - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 32); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_ROR(block, dest_reg, src_reg, REG_TEMP2); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 16); + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_ROR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + cs = cs; + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 8); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 8); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PFADD(codeblock_t *block, uop_t *uop) +static int +codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } else { + host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); } - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) + host_arm64_BFI(block, dest_reg, src_reg, 0, 16); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16 - (uop->imm_data & 15)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); } - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + host_arm64_BFI(block, dest_reg, src_reg, 0, 8); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); } - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRECPE/VRECPS)*/ - host_arm64_FMOV_S_ONE(block, REG_V_TEMP); - host_arm64_FDIV_S(block, dest_reg, REG_V_TEMP, src_reg_a); - host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ - host_arm64_FSQRT_S(block, REG_V_TEMP, src_reg_a); - host_arm64_FMOV_S_ONE(block, REG_V_TEMP); - host_arm64_FDIV_S(block, dest_reg, dest_reg, REG_V_TEMP); - host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm64_SCVTF_V2S(block, dest_reg, src_reg_a); - } - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SMULL_V4S_4H(block, REG_V_TEMP, src_reg_a, src_reg_b); - host_arm64_ADDP_V4S(block, dest_reg, REG_V_TEMP, REG_V_TEMP); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b); - host_arm64_SHRN_V4H_4S(block, dest_reg, dest_reg, 16); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_SHL_V4H(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_SHL_V2S(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_SHL_V2D(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm64_SSHR_V4H(block, dest_reg, src_reg, 15); - else - host_arm64_SSHR_V4H(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm64_SSHR_V2S(block, dest_reg, src_reg, 31); - else - host_arm64_SSHR_V2S(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm64_SSHR_V2D(block, dest_reg, src_reg, 63); - else - host_arm64_SSHR_V2D(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_USHR_V4H(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_USHR_V2S(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_USHR_V2D(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SUB_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SUB_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SUB_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 32); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_ROR(block, dest_reg, src_reg, REG_TEMP2); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 16); - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_ROR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - cs = cs; - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 8); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 8); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm64_MOV_REG(block, dest_reg, src_reg, 0); - } - else - { - host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); - } - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - host_arm64_BFI(block, dest_reg, src_reg, 0, 16); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16-(uop->imm_data & 15)); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - host_arm64_BFI(block, dest_reg, src_reg, 0, 8); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ROR(codeblock_t *block, uop_t *uop) +static int +codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ROR(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 15); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ROR(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 15); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm64_MOV_REG(block, dest_reg, src_reg, 0); - } - else - { - host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } else { + host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SAR(codeblock_t *block, uop_t *uop) +static int +codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ASR(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); - host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ASR(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); - host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHL(codeblock_t *block, uop_t *uop) +static int +codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_LSL(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_LSL(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_LSL(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_LSL(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_MOV_REG(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_MOV_REG(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHR(codeblock_t *block, uop_t *uop) +static int +codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_LSR(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_LSR(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_W16, uop->imm_data); + host_arm64_mov_imm(block, REG_W16, uop->imm_data); - if (in_range12_w((uintptr_t)uop->p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_W(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); + if (in_range12_w((uintptr_t) uop->p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_W(block, REG_W16, REG_CPUSTATE, (uintptr_t) uop->p - (uintptr_t) &cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); - return 0; + return 0; } -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +static int +codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_W16, uop->imm_data); + host_arm64_mov_imm(block, REG_W16, uop->imm_data); - if (in_range12_b((uintptr_t)uop->p - (uintptr_t)&cpu_state)) - host_arm64_STRB_IMM(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); + if (in_range12_b((uintptr_t) uop->p - (uintptr_t) &cpu_state)) + host_arm64_STRB_IMM(block, REG_W16, REG_CPUSTATE, (uintptr_t) uop->p - (uintptr_t) &cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); - return 0; + return 0; } -static int codegen_SUB(codeblock_t *block, uop_t *uop) +static int +codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_SUB_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); - host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); - host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_SUB_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BEQ_(block); + uop->p = host_arm64_BEQ_(block); - return 0; + return 0; } -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BNE_(block); + uop->p = host_arm64_BNE_(block); - return 0; + return 0; } -static int codegen_XOR(codeblock_t *block, uop_t *uop) +static int +codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_EOR_REG_V(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_EOR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_EOR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_EOR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("XOR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("XOR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, +const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & + UOP_MASK] + = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & + UOP_MASK] + = codegen_CALL_INSTRUCTION_FUNC, - [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_JMP & + UOP_MASK] + = codegen_JMP, - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_SEG & + UOP_MASK] + = codegen_LOAD_SEG, - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3, - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + [UOP_LOAD_FUNC_ARG_0_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3_IMM, - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_STORE_P_IMM & + UOP_MASK] + = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & + UOP_MASK] + = codegen_STORE_PTR_IMM_8, - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, + [UOP_MEM_LOAD_ABS & + UOP_MASK] + = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & + UOP_MASK] + = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & + UOP_MASK] + = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & + UOP_MASK] + = codegen_MEM_LOAD_DOUBLE, - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, + [UOP_MEM_STORE_ABS & + UOP_MASK] + = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & + UOP_MASK] + = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & + UOP_MASK] + = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & + UOP_MASK] + = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & + UOP_MASK] + = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & + UOP_MASK] + = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & + UOP_MASK] + = codegen_MEM_STORE_DOUBLE, - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + [UOP_MOV & + UOP_MASK] + = codegen_MOV, + [UOP_MOV_PTR & + UOP_MASK] + = codegen_MOV_PTR, + [UOP_MOV_IMM & + UOP_MASK] + = codegen_MOV_IMM, + [UOP_MOVSX & + UOP_MASK] + = codegen_MOVSX, + [UOP_MOVZX & + UOP_MASK] + = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & + UOP_MASK] + = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & + UOP_MASK] + = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & + UOP_MASK] + = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & + UOP_MASK] + = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_16, - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + [UOP_ADD & + UOP_MASK] + = codegen_ADD, + [UOP_ADD_IMM & + UOP_MASK] + = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & + UOP_MASK] + = codegen_ADD_LSHIFT, + [UOP_AND & + UOP_MASK] + = codegen_AND, + [UOP_AND_IMM & + UOP_MASK] + = codegen_AND_IMM, + [UOP_ANDN & + UOP_MASK] + = codegen_ANDN, + [UOP_OR & + UOP_MASK] + = codegen_OR, + [UOP_OR_IMM & + UOP_MASK] + = codegen_OR_IMM, + [UOP_SUB & + UOP_MASK] + = codegen_SUB, + [UOP_SUB_IMM & + UOP_MASK] + = codegen_SUB_IMM, + [UOP_XOR & + UOP_MASK] + = codegen_XOR, + [UOP_XOR_IMM & + UOP_MASK] + = codegen_XOR_IMM, - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, + [UOP_SAR & + UOP_MASK] + = codegen_SAR, + [UOP_SAR_IMM & + UOP_MASK] + = codegen_SAR_IMM, + [UOP_SHL & + UOP_MASK] + = codegen_SHL, + [UOP_SHL_IMM & + UOP_MASK] + = codegen_SHL_IMM, + [UOP_SHR & + UOP_MASK] + = codegen_SHR, + [UOP_SHR_IMM & + UOP_MASK] + = codegen_SHR_IMM, + [UOP_ROL & + UOP_MASK] + = codegen_ROL, + [UOP_ROL_IMM & + UOP_MASK] + = codegen_ROL_IMM, + [UOP_ROR & + UOP_MASK] + = codegen_ROR, + [UOP_ROR_IMM & + UOP_MASK] + = codegen_ROR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_IMM_JZ & + UOP_MASK] + = codegen_CMP_IMM_JZ, - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JB & + UOP_MASK] + = codegen_CMP_JB, + [UOP_CMP_JNBE & + UOP_MASK] + = codegen_CMP_JNBE, - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + [UOP_CMP_JNB_DEST & + UOP_MASK] + = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & + UOP_MASK] + = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & + UOP_MASK] + = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & + UOP_MASK] + = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & + UOP_MASK] + = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & + UOP_MASK] + = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & + UOP_MASK] + = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & + UOP_MASK] + = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & + UOP_MASK] + = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & + UOP_MASK] + = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & + UOP_MASK] + = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & + UOP_MASK] + = codegen_CMP_JZ_DEST, - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + [UOP_CMP_IMM_JNZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JZ_DEST, - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + [UOP_TEST_JNS_DEST & + UOP_MASK] + = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & + UOP_MASK] + = codegen_TEST_JS_DEST, - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, + [UOP_FP_ENTER & + UOP_MASK] + = codegen_FP_ENTER, + [UOP_MMX_ENTER & + UOP_MASK] + = codegen_MMX_ENTER, - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FADD & + UOP_MASK] + = codegen_FADD, + [UOP_FCOM & + UOP_MASK] + = codegen_FCOM, + [UOP_FDIV & + UOP_MASK] + = codegen_FDIV, + [UOP_FMUL & + UOP_MASK] + = codegen_FMUL, + [UOP_FSUB & + UOP_MASK] + = codegen_FSUB, - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, + [UOP_FABS & + UOP_MASK] + = codegen_FABS, + [UOP_FCHS & + UOP_MASK] + = codegen_FCHS, + [UOP_FSQRT & + UOP_MASK] + = codegen_FSQRT, + [UOP_FTST & + UOP_MASK] + = codegen_FTST, - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PACKSSWB & + UOP_MASK] + = codegen_PACKSSWB, + [UOP_PACKSSDW & + UOP_MASK] + = codegen_PACKSSDW, + [UOP_PACKUSWB & + UOP_MASK] + = codegen_PACKUSWB, - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PADDB & + UOP_MASK] + = codegen_PADDB, + [UOP_PADDW & + UOP_MASK] + = codegen_PADDW, + [UOP_PADDD & + UOP_MASK] + = codegen_PADDD, + [UOP_PADDSB & + UOP_MASK] + = codegen_PADDSB, + [UOP_PADDSW & + UOP_MASK] + = codegen_PADDSW, + [UOP_PADDUSB & + UOP_MASK] + = codegen_PADDUSB, + [UOP_PADDUSW & + UOP_MASK] + = codegen_PADDUSW, - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PCMPEQB & + UOP_MASK] + = codegen_PCMPEQB, + [UOP_PCMPEQW & + UOP_MASK] + = codegen_PCMPEQW, + [UOP_PCMPEQD & + UOP_MASK] + = codegen_PCMPEQD, + [UOP_PCMPGTB & + UOP_MASK] + = codegen_PCMPGTB, + [UOP_PCMPGTW & + UOP_MASK] + = codegen_PCMPGTW, + [UOP_PCMPGTD & + UOP_MASK] + = codegen_PCMPGTD, - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PF2ID & + UOP_MASK] + = codegen_PF2ID, + [UOP_PFADD & + UOP_MASK] + = codegen_PFADD, + [UOP_PFCMPEQ & + UOP_MASK] + = codegen_PFCMPEQ, + [UOP_PFCMPGE & + UOP_MASK] + = codegen_PFCMPGE, + [UOP_PFCMPGT & + UOP_MASK] + = codegen_PFCMPGT, + [UOP_PFMAX & + UOP_MASK] + = codegen_PFMAX, + [UOP_PFMIN & + UOP_MASK] + = codegen_PFMIN, + [UOP_PFMUL & + UOP_MASK] + = codegen_PFMUL, + [UOP_PFRCP & + UOP_MASK] + = codegen_PFRCP, + [UOP_PFRSQRT & + UOP_MASK] + = codegen_PFRSQRT, + [UOP_PFSUB & + UOP_MASK] + = codegen_PFSUB, + [UOP_PI2FD & + UOP_MASK] + = codegen_PI2FD, - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PMADDWD & + UOP_MASK] + = codegen_PMADDWD, + [UOP_PMULHW & + UOP_MASK] + = codegen_PMULHW, + [UOP_PMULLW & + UOP_MASK] + = codegen_PMULLW, - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSLLW_IMM & + UOP_MASK] + = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & + UOP_MASK] + = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & + UOP_MASK] + = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & + UOP_MASK] + = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & + UOP_MASK] + = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & + UOP_MASK] + = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & + UOP_MASK] + = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & + UOP_MASK] + = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & + UOP_MASK] + = codegen_PSRLQ_IMM, - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + [UOP_PSUBB & + UOP_MASK] + = codegen_PSUBB, + [UOP_PSUBW & + UOP_MASK] + = codegen_PSUBW, + [UOP_PSUBD & + UOP_MASK] + = codegen_PSUBD, + [UOP_PSUBSB & + UOP_MASK] + = codegen_PSUBSB, + [UOP_PSUBSW & + UOP_MASK] + = codegen_PSUBSW, + [UOP_PSUBUSB & + UOP_MASK] + = codegen_PSUBUSB, + [UOP_PSUBUSW & + UOP_MASK] + = codegen_PSUBUSW, - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + [UOP_PUNPCKHBW & + UOP_MASK] + = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & + UOP_MASK] + = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & + UOP_MASK] + = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & + UOP_MASK] + = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & + UOP_MASK] + = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & + UOP_MASK] + = codegen_PUNPCKLDQ, - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP + [UOP_NOP_BARRIER & + UOP_MASK] + = codegen_NOP }; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDRB_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_8 - not in range\n"); + if (in_range12_b((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDRB_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_8 - not in range\n"); } -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_16 - not in range\n"); + if (in_range12_h((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_16 - not in range\n"); } -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_32 - not in range\n"); + if (in_range12_w((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_32 - not in range\n"); } -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_double - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_double - not in range\n"); } -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_X(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_pointer - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDR_IMM_X(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_pointer - not in range\n"); } -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_double - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_double - not in range\n"); } -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_LDRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_8 - not in range\n"); + if (in_range12_b((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_8 - not in range\n"); } -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_16 - not in range\n"); + if (in_range12_h((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_16 - not in range\n"); } -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_32 - not in range\n"); + if (in_range12_w((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_32 - not in range\n"); } -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_double - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_double - not in range\n"); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_double - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_double - not in range\n"); } -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_Q(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_ptr - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_Q(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_ptr - not in range\n"); } -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (in_range12_h(stack_offset)) - host_arm64_LDRH_IMM(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_read_32_stack - not in range\n"); + if (in_range12_h(stack_offset)) + host_arm64_LDRH_IMM(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_read_32_stack - not in range\n"); } -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (in_range12_w(stack_offset)) - host_arm64_LDR_IMM_W(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_read_32_stack - not in range\n"); + if (in_range12_w(stack_offset)) + host_arm64_LDR_IMM_W(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_read_32_stack - not in range\n"); } -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (in_range12_q(stack_offset)) - host_arm64_LDR_IMM_X(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_read_pointer_stack - not in range\n"); + if (in_range12_q(stack_offset)) + host_arm64_LDR_IMM_X(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_read_pointer_stack - not in range\n"); } -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); + host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); + host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - if (in_range12_w(stack_offset)) - host_arm64_STR_IMM_W(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_write_32_stack - not in range\n"); + if (in_range12_w(stack_offset)) + host_arm64_STR_IMM_W(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_write_32_stack - not in range\n"); } -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); + host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); + host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } -void codegen_set_jump_dest(codeblock_t *block, void *p) +void +codegen_set_jump_dest(codeblock_t *block, void *p) { - host_arm64_branch_set_offset(p, &block_write_data[block_pos]); + host_arm64_branch_set_offset(p, &block_write_data[block_pos]); } #endif diff --git a/src/codegen_new/codegen_backend_arm_defs.h b/src/codegen_new/codegen_backend_arm_defs.h index 74567998a..745854429 100644 --- a/src/codegen_new/codegen_backend_arm_defs.h +++ b/src/codegen_new/codegen_backend_arm_defs.h @@ -1,72 +1,71 @@ -#define REG_R0 0 -#define REG_R1 1 -#define REG_R2 2 -#define REG_R3 3 -#define REG_R4 4 -#define REG_R5 5 -#define REG_R6 6 -#define REG_R7 7 -#define REG_R8 8 -#define REG_R9 9 -#define REG_R10 10 -#define REG_R11 11 -#define REG_R12 12 -#define REG_HOST_SP 13 -#define REG_LR 14 -#define REG_PC 15 +#define REG_R0 0 +#define REG_R1 1 +#define REG_R2 2 +#define REG_R3 3 +#define REG_R4 4 +#define REG_R5 5 +#define REG_R6 6 +#define REG_R7 7 +#define REG_R8 8 +#define REG_R9 9 +#define REG_R10 10 +#define REG_R11 11 +#define REG_R12 12 +#define REG_HOST_SP 13 +#define REG_LR 14 +#define REG_PC 15 -#define REG_ARG0 REG_R0 -#define REG_ARG1 REG_R1 -#define REG_ARG2 REG_R2 -#define REG_ARG3 REG_R3 +#define REG_ARG0 REG_R0 +#define REG_ARG1 REG_R1 +#define REG_ARG2 REG_R2 +#define REG_ARG3 REG_R3 -#define REG_CPUSTATE REG_R10 +#define REG_CPUSTATE REG_R10 -#define REG_TEMP REG_R3 -#define REG_TEMP2 REG_R2 +#define REG_TEMP REG_R3 +#define REG_TEMP2 REG_R2 -#define REG_D0 0 -#define REG_D1 1 -#define REG_D2 2 -#define REG_D3 3 -#define REG_D4 4 -#define REG_D5 5 -#define REG_D6 6 -#define REG_D7 7 -#define REG_D8 8 -#define REG_D9 9 -#define REG_D10 10 -#define REG_D11 11 -#define REG_D12 12 -#define REG_D13 13 -#define REG_D14 14 -#define REG_D15 15 +#define REG_D0 0 +#define REG_D1 1 +#define REG_D2 2 +#define REG_D3 3 +#define REG_D4 4 +#define REG_D5 5 +#define REG_D6 6 +#define REG_D7 7 +#define REG_D8 8 +#define REG_D9 9 +#define REG_D10 10 +#define REG_D11 11 +#define REG_D12 12 +#define REG_D13 13 +#define REG_D14 14 +#define REG_D15 15 -#define REG_D_TEMP REG_D0 -#define REG_Q_TEMP REG_D0 -#define REG_Q_TEMP_2 REG_D2 +#define REG_D_TEMP REG_D0 +#define REG_Q_TEMP REG_D0 +#define REG_Q_TEMP_2 REG_D2 -#define REG_MASK_R0 (1 << REG_R0) -#define REG_MASK_R1 (1 << REG_R1) -#define REG_MASK_R2 (1 << REG_R2) -#define REG_MASK_R3 (1 << REG_R3) -#define REG_MASK_R4 (1 << REG_R4) -#define REG_MASK_R5 (1 << REG_R5) -#define REG_MASK_R6 (1 << REG_R6) -#define REG_MASK_R7 (1 << REG_R7) -#define REG_MASK_R8 (1 << REG_R8) -#define REG_MASK_R9 (1 << REG_R9) -#define REG_MASK_R10 (1 << REG_R10) -#define REG_MASK_R11 (1 << REG_R11) -#define REG_MASK_R12 (1 << REG_R12) -#define REG_MASK_SP (1 << REG_HOST_SP) -#define REG_MASK_LR (1 << REG_LR) -#define REG_MASK_PC (1 << REG_PC) +#define REG_MASK_R0 (1 << REG_R0) +#define REG_MASK_R1 (1 << REG_R1) +#define REG_MASK_R2 (1 << REG_R2) +#define REG_MASK_R3 (1 << REG_R3) +#define REG_MASK_R4 (1 << REG_R4) +#define REG_MASK_R5 (1 << REG_R5) +#define REG_MASK_R6 (1 << REG_R6) +#define REG_MASK_R7 (1 << REG_R7) +#define REG_MASK_R8 (1 << REG_R8) +#define REG_MASK_R9 (1 << REG_R9) +#define REG_MASK_R10 (1 << REG_R10) +#define REG_MASK_R11 (1 << REG_R11) +#define REG_MASK_R12 (1 << REG_R12) +#define REG_MASK_SP (1 << REG_HOST_SP) +#define REG_MASK_LR (1 << REG_LR) +#define REG_MASK_PC (1 << REG_PC) -#define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | \ - REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) +#define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) -#define CODEGEN_HOST_REGS 7 +#define CODEGEN_HOST_REGS 7 #define CODEGEN_HOST_FP_REGS 8 extern void *codegen_mem_load_byte; diff --git a/src/codegen_new/codegen_backend_arm_ops.c b/src/codegen_new/codegen_backend_arm_ops.c index 43d1ea090..e56b2f6e5 100644 --- a/src/codegen_new/codegen_backend_arm_ops.c +++ b/src/codegen_new/codegen_backend_arm_ops.c @@ -1,1274 +1,1395 @@ #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm_defs.h" -#include "codegen_backend_arm_ops.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm_defs.h" +# include "codegen_backend_arm_ops.h" -#define Rm(x) (x) -#define Rs(x) ((x) << 8) -#define Rd(x) ((x) << 12) -#define Rt(x) ((x) << 12) -#define Rn(x) ((x) << 16) -#define Rt2(x) ((x) << 16) +# define Rm(x) (x) +# define Rs(x) ((x) << 8) +# define Rd(x) ((x) << 12) +# define Rt(x) ((x) << 12) +# define Rn(x) ((x) << 16) +# define Rt2(x) ((x) << 16) -#define Vm(x) (x) -#define Vd(x) ((x) << 12) -#define Vn(x) ((x) << 16) +# define Vm(x) (x) +# define Vd(x) ((x) << 12) +# define Vn(x) ((x) << 16) -#define DATA_OFFSET_UP (1 << 23) -#define DATA_OFFSET_DOWN (0 << 23) +# define DATA_OFFSET_UP (1 << 23) +# define DATA_OFFSET_DOWN (0 << 23) -#define OPCODE_SHIFT 20 -#define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) -#define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) -#define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) -#define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) -#define OPCODE_B (0xa0 << OPCODE_SHIFT) -#define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) -#define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) -#define OPCODE_BL (0xb0 << OPCODE_SHIFT) -#define OPCODE_CMN_IMM (0x37 << OPCODE_SHIFT) -#define OPCODE_CMN_REG (0x17 << OPCODE_SHIFT) -#define OPCODE_CMP_IMM (0x35 << OPCODE_SHIFT) -#define OPCODE_CMP_REG (0x15 << OPCODE_SHIFT) -#define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) -#define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) -#define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) -#define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) -#define OPCODE_LDR_IMM_POST (0x41 << OPCODE_SHIFT) -#define OPCODE_LDR_REG (0x79 << OPCODE_SHIFT) -#define OPCODE_LDRB_IMM (0x55 << OPCODE_SHIFT) -#define OPCODE_LDRB_REG (0x7d << OPCODE_SHIFT) -#define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) -#define OPCODE_MOVT_IMM (0x34 << OPCODE_SHIFT) -#define OPCODE_MOVW_IMM (0x30 << OPCODE_SHIFT) -#define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) -#define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) -#define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) -#define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) -#define OPCODE_RSB_IMM (0x26 << OPCODE_SHIFT) -#define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) -#define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) -#define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) -#define OPCODE_STR_IMM_WB (0x52 << OPCODE_SHIFT) -#define OPCODE_STR_REG (0x78 << OPCODE_SHIFT) -#define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) -#define OPCODE_STRB_REG (0x7c << OPCODE_SHIFT) -#define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) -#define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) -#define OPCODE_TST_IMM (0x31 << OPCODE_SHIFT) -#define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) +# define OPCODE_SHIFT 20 +# define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) +# define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) +# define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) +# define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) +# define OPCODE_B (0xa0 << OPCODE_SHIFT) +# define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) +# define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) +# define OPCODE_BL (0xb0 << OPCODE_SHIFT) +# define OPCODE_CMN_IMM (0x37 << OPCODE_SHIFT) +# define OPCODE_CMN_REG (0x17 << OPCODE_SHIFT) +# define OPCODE_CMP_IMM (0x35 << OPCODE_SHIFT) +# define OPCODE_CMP_REG (0x15 << OPCODE_SHIFT) +# define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) +# define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) +# define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) +# define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) +# define OPCODE_LDR_IMM_POST (0x41 << OPCODE_SHIFT) +# define OPCODE_LDR_REG (0x79 << OPCODE_SHIFT) +# define OPCODE_LDRB_IMM (0x55 << OPCODE_SHIFT) +# define OPCODE_LDRB_REG (0x7d << OPCODE_SHIFT) +# define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) +# define OPCODE_MOVT_IMM (0x34 << OPCODE_SHIFT) +# define OPCODE_MOVW_IMM (0x30 << OPCODE_SHIFT) +# define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) +# define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) +# define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) +# define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) +# define OPCODE_RSB_IMM (0x26 << OPCODE_SHIFT) +# define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) +# define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) +# define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) +# define OPCODE_STR_IMM_WB (0x52 << OPCODE_SHIFT) +# define OPCODE_STR_REG (0x78 << OPCODE_SHIFT) +# define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) +# define OPCODE_STRB_REG (0x7c << OPCODE_SHIFT) +# define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) +# define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) +# define OPCODE_TST_IMM (0x31 << OPCODE_SHIFT) +# define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) -#define OPCODE_BFI 0xe7c00010 -#define OPCODE_BLX 0xe12fff30 -#define OPCODE_BX 0xe12fff10 -#define OPCODE_LDRH_IMM 0xe1d000b0 -#define OPCODE_LDRH_REG 0xe19000b0 -#define OPCODE_STRH_IMM 0xe1c000b0 -#define OPCODE_STRH_REG 0xe18000b0 -#define OPCODE_SXTB 0xe6af0070 -#define OPCODE_SXTH 0xe6bf0070 -#define OPCODE_UADD8 0xe6500f90 -#define OPCODE_UADD16 0xe6500f10 -#define OPCODE_USUB8 0xe6500ff0 -#define OPCODE_USUB16 0xe6500f70 -#define OPCODE_UXTB 0xe6ef0070 -#define OPCODE_UXTH 0xe6ff0070 -#define OPCODE_VABS_D 0xeeb00bc0 -#define OPCODE_VADD 0xee300b00 -#define OPCODE_VADD_I8 0xf2000800 -#define OPCODE_VADD_I16 0xf2100800 -#define OPCODE_VADD_I32 0xf2200800 -#define OPCODE_VADD_F32 0xf2000d00 -#define OPCODE_VAND_D 0xf2000110 -#define OPCODE_VBIC_D 0xf2100110 -#define OPCODE_VCEQ_F32 0xf2000e00 -#define OPCODE_VCEQ_I8 0xf3000810 -#define OPCODE_VCEQ_I16 0xf3100810 -#define OPCODE_VCEQ_I32 0xf3200810 -#define OPCODE_VCGE_F32 0xf3000e00 -#define OPCODE_VCGT_F32 0xf3200e00 -#define OPCODE_VCGT_S8 0xf2000300 -#define OPCODE_VCGT_S16 0xf2100300 -#define OPCODE_VCGT_S32 0xf2200300 -#define OPCODE_VCMP_D 0xeeb40b40 -#define OPCODE_VCVT_D_IS 0xeeb80bc0 -#define OPCODE_VCVT_D_S 0xeeb70ac0 -#define OPCODE_VCVT_F32_S32 0xf3bb0700 -#define OPCODE_VCVT_IS_D 0xeebd0bc0 -#define OPCODE_VCVT_S32_F32 0xf3bb0600 -#define OPCODE_VCVT_S_D 0xeeb70bc0 -#define OPCODE_VCVTR_IS_D 0xeebd0b40 -#define OPCODE_VDIV 0xee800b00 -#define OPCODE_VDIV_S 0xee800a00 -#define OPCODE_VDUP_32 0xf3b40c00 -#define OPCODE_VEOR_D 0xf3000110 -#define OPCODE_VLDR_D 0xed900b00 -#define OPCODE_VLDR_S 0xed900a00 -#define OPCODE_VMAX_F32 0xf200f00 -#define OPCODE_VMIN_F32 0xf220f00 -#define OPCODE_VMOV_32_S 0xee100a10 -#define OPCODE_VMOV_64_D 0xec500b10 -#define OPCODE_VMOV_D_64 0xec400b10 -#define OPCODE_VMOV_S_32 0xee000a10 -#define OPCODE_VMOV_D_D 0xeeb00b40 -#define OPCODE_VMOVN_I32 0xf3b60200 -#define OPCODE_VMOVN_I64 0xf3ba0200 -#define OPCODE_VMOV_F32_ONE 0xf2870f10 -#define OPCODE_VMRS_APSR 0xeef1fa10 -#define OPCODE_VMSR_FPSCR 0xeee10a10 -#define OPCODE_VMUL 0xee200b00 -#define OPCODE_VMUL_F32 0xf3000d10 -#define OPCODE_VMUL_S16 0xf2100910 -#define OPCODE_VMULL_S16 0xf2900c00 -#define OPCODE_VNEG_D 0xeeb10b40 -#define OPCODE_VORR_D 0xf2200110 -#define OPCODE_VPADDL_S16 0xf3b40200 -#define OPCODE_VPADDL_S32 0xf3b80200 -#define OPCODE_VPADDL_Q_S32 0xf3b80240 -#define OPCODE_VQADD_S8 0xf2000010 -#define OPCODE_VQADD_S16 0xf2100010 -#define OPCODE_VQADD_U8 0xf3000010 -#define OPCODE_VQADD_U16 0xf3100010 -#define OPCODE_VQMOVN_S16 0xf3b20280 -#define OPCODE_VQMOVN_S32 0xf3b60280 -#define OPCODE_VQMOVN_U16 0xf3b202c0 -#define OPCODE_VQSUB_S8 0xf2000210 -#define OPCODE_VQSUB_S16 0xf2100210 -#define OPCODE_VQSUB_U8 0xf3000210 -#define OPCODE_VQSUB_U16 0xf3100210 -#define OPCODE_VSHL_D_IMM_16 0xf2900510 -#define OPCODE_VSHL_D_IMM_32 0xf2a00510 -#define OPCODE_VSHL_D_IMM_64 0xf2800590 -#define OPCODE_VSHR_D_S16 0xf2900010 -#define OPCODE_VSHR_D_S32 0xf2a00010 -#define OPCODE_VSHR_D_S64 0xf2800090 -#define OPCODE_VSHR_D_U16 0xf3900010 -#define OPCODE_VSHR_D_U32 0xf3a00010 -#define OPCODE_VSHR_D_U64 0xf3800090 -#define OPCODE_VSHRN 0xf2800810 -#define OPCODE_VSQRT_D 0xeeb10bc0 -#define OPCODE_VSQRT_S 0xeeb10ac0 -#define OPCODE_VSTR_D 0xed800b00 -#define OPCODE_VSTR_S 0xed800a00 -#define OPCODE_VSUB 0xee300b40 -#define OPCODE_VSUB_I8 0xf3000800 -#define OPCODE_VSUB_I16 0xf3100800 -#define OPCODE_VSUB_I32 0xf3200800 -#define OPCODE_VSUB_F32 0xf3000d00 -#define OPCODE_VZIP_D8 0xf3b20180 -#define OPCODE_VZIP_D16 0xf3b60180 -#define OPCODE_VZIP_D32 0xf3ba0080 +# define OPCODE_BFI 0xe7c00010 +# define OPCODE_BLX 0xe12fff30 +# define OPCODE_BX 0xe12fff10 +# define OPCODE_LDRH_IMM 0xe1d000b0 +# define OPCODE_LDRH_REG 0xe19000b0 +# define OPCODE_STRH_IMM 0xe1c000b0 +# define OPCODE_STRH_REG 0xe18000b0 +# define OPCODE_SXTB 0xe6af0070 +# define OPCODE_SXTH 0xe6bf0070 +# define OPCODE_UADD8 0xe6500f90 +# define OPCODE_UADD16 0xe6500f10 +# define OPCODE_USUB8 0xe6500ff0 +# define OPCODE_USUB16 0xe6500f70 +# define OPCODE_UXTB 0xe6ef0070 +# define OPCODE_UXTH 0xe6ff0070 +# define OPCODE_VABS_D 0xeeb00bc0 +# define OPCODE_VADD 0xee300b00 +# define OPCODE_VADD_I8 0xf2000800 +# define OPCODE_VADD_I16 0xf2100800 +# define OPCODE_VADD_I32 0xf2200800 +# define OPCODE_VADD_F32 0xf2000d00 +# define OPCODE_VAND_D 0xf2000110 +# define OPCODE_VBIC_D 0xf2100110 +# define OPCODE_VCEQ_F32 0xf2000e00 +# define OPCODE_VCEQ_I8 0xf3000810 +# define OPCODE_VCEQ_I16 0xf3100810 +# define OPCODE_VCEQ_I32 0xf3200810 +# define OPCODE_VCGE_F32 0xf3000e00 +# define OPCODE_VCGT_F32 0xf3200e00 +# define OPCODE_VCGT_S8 0xf2000300 +# define OPCODE_VCGT_S16 0xf2100300 +# define OPCODE_VCGT_S32 0xf2200300 +# define OPCODE_VCMP_D 0xeeb40b40 +# define OPCODE_VCVT_D_IS 0xeeb80bc0 +# define OPCODE_VCVT_D_S 0xeeb70ac0 +# define OPCODE_VCVT_F32_S32 0xf3bb0700 +# define OPCODE_VCVT_IS_D 0xeebd0bc0 +# define OPCODE_VCVT_S32_F32 0xf3bb0600 +# define OPCODE_VCVT_S_D 0xeeb70bc0 +# define OPCODE_VCVTR_IS_D 0xeebd0b40 +# define OPCODE_VDIV 0xee800b00 +# define OPCODE_VDIV_S 0xee800a00 +# define OPCODE_VDUP_32 0xf3b40c00 +# define OPCODE_VEOR_D 0xf3000110 +# define OPCODE_VLDR_D 0xed900b00 +# define OPCODE_VLDR_S 0xed900a00 +# define OPCODE_VMAX_F32 0xf200f00 +# define OPCODE_VMIN_F32 0xf220f00 +# define OPCODE_VMOV_32_S 0xee100a10 +# define OPCODE_VMOV_64_D 0xec500b10 +# define OPCODE_VMOV_D_64 0xec400b10 +# define OPCODE_VMOV_S_32 0xee000a10 +# define OPCODE_VMOV_D_D 0xeeb00b40 +# define OPCODE_VMOVN_I32 0xf3b60200 +# define OPCODE_VMOVN_I64 0xf3ba0200 +# define OPCODE_VMOV_F32_ONE 0xf2870f10 +# define OPCODE_VMRS_APSR 0xeef1fa10 +# define OPCODE_VMSR_FPSCR 0xeee10a10 +# define OPCODE_VMUL 0xee200b00 +# define OPCODE_VMUL_F32 0xf3000d10 +# define OPCODE_VMUL_S16 0xf2100910 +# define OPCODE_VMULL_S16 0xf2900c00 +# define OPCODE_VNEG_D 0xeeb10b40 +# define OPCODE_VORR_D 0xf2200110 +# define OPCODE_VPADDL_S16 0xf3b40200 +# define OPCODE_VPADDL_S32 0xf3b80200 +# define OPCODE_VPADDL_Q_S32 0xf3b80240 +# define OPCODE_VQADD_S8 0xf2000010 +# define OPCODE_VQADD_S16 0xf2100010 +# define OPCODE_VQADD_U8 0xf3000010 +# define OPCODE_VQADD_U16 0xf3100010 +# define OPCODE_VQMOVN_S16 0xf3b20280 +# define OPCODE_VQMOVN_S32 0xf3b60280 +# define OPCODE_VQMOVN_U16 0xf3b202c0 +# define OPCODE_VQSUB_S8 0xf2000210 +# define OPCODE_VQSUB_S16 0xf2100210 +# define OPCODE_VQSUB_U8 0xf3000210 +# define OPCODE_VQSUB_U16 0xf3100210 +# define OPCODE_VSHL_D_IMM_16 0xf2900510 +# define OPCODE_VSHL_D_IMM_32 0xf2a00510 +# define OPCODE_VSHL_D_IMM_64 0xf2800590 +# define OPCODE_VSHR_D_S16 0xf2900010 +# define OPCODE_VSHR_D_S32 0xf2a00010 +# define OPCODE_VSHR_D_S64 0xf2800090 +# define OPCODE_VSHR_D_U16 0xf3900010 +# define OPCODE_VSHR_D_U32 0xf3a00010 +# define OPCODE_VSHR_D_U64 0xf3800090 +# define OPCODE_VSHRN 0xf2800810 +# define OPCODE_VSQRT_D 0xeeb10bc0 +# define OPCODE_VSQRT_S 0xeeb10ac0 +# define OPCODE_VSTR_D 0xed800b00 +# define OPCODE_VSTR_S 0xed800a00 +# define OPCODE_VSUB 0xee300b40 +# define OPCODE_VSUB_I8 0xf3000800 +# define OPCODE_VSUB_I16 0xf3100800 +# define OPCODE_VSUB_I32 0xf3200800 +# define OPCODE_VSUB_F32 0xf3000d00 +# define OPCODE_VZIP_D8 0xf3b20180 +# define OPCODE_VZIP_D16 0xf3b60180 +# define OPCODE_VZIP_D32 0xf3ba0080 -#define B_OFFSET(x) (((x) >> 2) & 0xffffff) +# define B_OFFSET(x) (((x) >> 2) & 0xffffff) -#define SHIFT_TYPE_SHIFT 5 -#define SHIFT_TYPE_LSL (0 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_LSR (1 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_ASR (2 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_ROR (3 << SHIFT_TYPE_SHIFT) +# define SHIFT_TYPE_SHIFT 5 +# define SHIFT_TYPE_LSL (0 << SHIFT_TYPE_SHIFT) +# define SHIFT_TYPE_LSR (1 << SHIFT_TYPE_SHIFT) +# define SHIFT_TYPE_ASR (2 << SHIFT_TYPE_SHIFT) +# define SHIFT_TYPE_ROR (3 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_IMM (0 << 4) -#define SHIFT_TYPE_REG (1 << 4) +# define SHIFT_TYPE_IMM (0 << 4) +# define SHIFT_TYPE_REG (1 << 4) -#define SHIFT_IMM_SHIFT 7 -#define SHIFT_ASR_IMM(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) -#define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) -#define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) -#define SHIFT_ROR_IMM(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +# define SHIFT_IMM_SHIFT 7 +# define SHIFT_ASR_IMM(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +# define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +# define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +# define SHIFT_ROR_IMM(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) -#define SHIFT_ASR_REG(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_REG | Rs(x)) -#define SHIFT_LSL_REG(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_REG | Rs(x)) -#define SHIFT_LSR_REG(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_REG | Rs(x)) -#define SHIFT_ROR_REG(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_REG | Rs(x)) +# define SHIFT_ASR_REG(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_REG | Rs(x)) +# define SHIFT_LSL_REG(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_REG | Rs(x)) +# define SHIFT_LSR_REG(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_REG | Rs(x)) +# define SHIFT_ROR_REG(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_REG | Rs(x)) -#define BFI_lsb(lsb) ((lsb) << 7) -#define BFI_msb(msb) ((msb) << 16) +# define BFI_lsb(lsb) ((lsb) << 7) +# define BFI_msb(msb) ((msb) << 16) -#define UXTB_ROTATE(rotate) (((rotate) >> 3) << 10) +# define UXTB_ROTATE(rotate) (((rotate) >> 3) << 10) -#define MOVT_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) -#define MOVW_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) +# define MOVT_IMM(imm) (((imm) &0xfff) | (((imm) &0xf000) << 4)) +# define MOVW_IMM(imm) (((imm) &0xfff) | (((imm) &0xf000) << 4)) -#define LDRH_IMM(imm) (((imm) & 0xf) | (((imm) & 0xf0) << 4)) -#define STRH_IMM(imm) LDRH_IMM(imm) +# define LDRH_IMM(imm) (((imm) &0xf) | (((imm) &0xf0) << 4)) +# define STRH_IMM(imm) LDRH_IMM(imm) -#define VSHIFT_IMM(shift) ((shift) << 16) +# define VSHIFT_IMM(shift) ((shift) << 16) -#define VSHIFT_IMM_32(shift) (((16 - (shift)) | 0x10) << 16) +# define VSHIFT_IMM_32(shift) (((16 - (shift)) | 0x10) << 16) -#define VDUP_32_IMM(imm) ((imm) << 19) +# define VDUP_32_IMM(imm) ((imm) << 19) static void codegen_allocate_new_block(codeblock_t *block); -static inline void codegen_addlong(codeblock_t *block, uint32_t val) +static inline void +codegen_addlong(codeblock_t *block, uint32_t val) { - if (block_pos >= (BLOCK_MAX-4)) - codegen_allocate_new_block(block); - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; + if (block_pos >= (BLOCK_MAX - 4)) + codegen_allocate_new_block(block); + *(uint32_t *) &block_write_data[block_pos] = val; + block_pos += 4; } -static void codegen_allocate_new_block(codeblock_t *block) +static void +codegen_allocate_new_block(codeblock_t *block) { - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - uint32_t offset = ((uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]) - 8; + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + uint32_t offset = ((uintptr_t) new_ptr - (uintptr_t) &block_write_data[block_pos]) - 8; - /*Add a jump instruction to the new block*/ - *(uint32_t *)&block_write_data[block_pos] = COND_AL | OPCODE_B | B_OFFSET(offset); + /*Add a jump instruction to the new block*/ + *(uint32_t *) &block_write_data[block_pos] = COND_AL | OPCODE_B | B_OFFSET(offset); - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; } -static inline void codegen_alloc_4(codeblock_t *block) +static inline void +codegen_alloc_4(codeblock_t *block) { - if (block_pos >= (BLOCK_MAX-4)) - codegen_allocate_new_block(block); + if (block_pos >= (BLOCK_MAX - 4)) + codegen_allocate_new_block(block); } -void codegen_alloc(codeblock_t *block, int size) +void +codegen_alloc(codeblock_t *block, int size) { - if (block_pos >= (BLOCK_MAX-size)) - codegen_allocate_new_block(block); + if (block_pos >= (BLOCK_MAX - size)) + codegen_allocate_new_block(block); } -static inline uint32_t arm_data_offset(int offset) +static inline uint32_t +arm_data_offset(int offset) { - if (offset < -0xffc || offset > 0xffc) - fatal("arm_data_offset out of range - %i\n", offset); + if (offset < -0xffc || offset > 0xffc) + fatal("arm_data_offset out of range - %i\n", offset); - if (offset >= 0) - return offset | DATA_OFFSET_UP; - return (-offset) | DATA_OFFSET_DOWN; + if (offset >= 0) + return offset | DATA_OFFSET_UP; + return (-offset) | DATA_OFFSET_DOWN; } -static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) +static inline int +get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) { - int shift = 0; - if (!(imm_data & 0xffff)) - { - shift += 16; - imm_data >>= 16; - } - if (!(imm_data & 0xff)) - { - shift += 8; - imm_data >>= 8; - } - if (!(imm_data & 0xf)) - { - shift += 4; - imm_data >>= 4; - } - if (!(imm_data & 0x3)) - { - shift += 2; - imm_data >>= 2; - } - if (imm_data > 0xff) /*Note - should handle rotation round the word*/ - return 0; - *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); - return 1; + int shift = 0; + if (!(imm_data & 0xffff)) { + shift += 16; + imm_data >>= 16; + } + if (!(imm_data & 0xff)) { + shift += 8; + imm_data >>= 8; + } + if (!(imm_data & 0xf)) { + shift += 4; + imm_data >>= 4; + } + if (!(imm_data & 0x3)) { + shift += 2; + imm_data >>= 2; + } + if (imm_data > 0xff) /*Note - should handle rotation round the word*/ + return 0; + *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); + return 1; } -static inline int in_range(void *addr, void *base) +static inline int +in_range(void *addr, void *base) { - int diff = (uintptr_t)addr - (uintptr_t)base; + int diff = (uintptr_t) addr - (uintptr_t) base; - if (diff < -4095 || diff > 4095) - return 0; - return 1; + if (diff < -4095 || diff > 4095) + return 0; + return 1; } void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -//void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +// void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if ((int32_t) imm < 0 && imm != 0x80000000) { + host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t) imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else if (get_arm_imm(~imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else if (get_arm_imm(~imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_B(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_B(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - { - host_arm_MOV_IMM(block, REG_R3, dest_addr); - host_arm_BX(block, REG_R3); - } - else - codegen_addlong(block, COND_AL | OPCODE_B | B_OFFSET(offset)); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { + host_arm_MOV_IMM(block, REG_R3, dest_addr); + host_arm_BX(block, REG_R3); + } else + codegen_addlong(block, COND_AL | OPCODE_B | B_OFFSET(offset)); } -void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +void +host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { - codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); } -void host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else if (get_arm_imm(~imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_BIC_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else if (get_arm_imm(~imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_BIC_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_BL(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_BL(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - { - host_arm_MOV_IMM(block, REG_R3, dest_addr); - host_arm_BLX(block, REG_R3); - } - else - codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { + host_arm_MOV_IMM(block, REG_R3, dest_addr); + host_arm_BLX(block, REG_R3); + } else + codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); } -void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - { - host_arm_MOV_IMM(block, REG_R1, dest_addr); - host_arm_BLX(block, REG_R1); - } - else - codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { + host_arm_MOV_IMM(block, REG_R1, dest_addr); + host_arm_BLX(block, REG_R1); + } else + codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); } -void host_arm_BLX(codeblock_t *block, int addr_reg) +void +host_arm_BLX(codeblock_t *block, int addr_reg) { - codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); + codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); } -uint32_t *host_arm_BCC_(codeblock_t *block) +uint32_t * +host_arm_BCC_(codeblock_t *block) { - codegen_addlong(block, COND_CC | OPCODE_B); + codegen_addlong(block, COND_CC | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BCS_(codeblock_t *block) +uint32_t * +host_arm_BCS_(codeblock_t *block) { - codegen_addlong(block, COND_CS | OPCODE_B); + codegen_addlong(block, COND_CS | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BEQ_(codeblock_t *block) +uint32_t * +host_arm_BEQ_(codeblock_t *block) { - codegen_addlong(block, COND_EQ | OPCODE_B); + codegen_addlong(block, COND_EQ | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BGE_(codeblock_t *block) +uint32_t * +host_arm_BGE_(codeblock_t *block) { - codegen_addlong(block, COND_GE | OPCODE_B); + codegen_addlong(block, COND_GE | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BGT_(codeblock_t *block) +uint32_t * +host_arm_BGT_(codeblock_t *block) { - codegen_addlong(block, COND_GT | OPCODE_B); + codegen_addlong(block, COND_GT | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BHI_(codeblock_t *block) +uint32_t * +host_arm_BHI_(codeblock_t *block) { - codegen_addlong(block, COND_HI | OPCODE_B); + codegen_addlong(block, COND_HI | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BLE_(codeblock_t *block) +uint32_t * +host_arm_BLE_(codeblock_t *block) { - codegen_addlong(block, COND_LE | OPCODE_B); + codegen_addlong(block, COND_LE | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BLS_(codeblock_t *block) +uint32_t * +host_arm_BLS_(codeblock_t *block) { - codegen_addlong(block, COND_LS | OPCODE_B); + codegen_addlong(block, COND_LS | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BLT_(codeblock_t *block) +uint32_t * +host_arm_BLT_(codeblock_t *block) { - codegen_addlong(block, COND_LT | OPCODE_B); + codegen_addlong(block, COND_LT | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BMI_(codeblock_t *block) +uint32_t * +host_arm_BMI_(codeblock_t *block) { - codegen_addlong(block, COND_MI | OPCODE_B); + codegen_addlong(block, COND_MI | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BNE_(codeblock_t *block) +uint32_t * +host_arm_BNE_(codeblock_t *block) { - codegen_addlong(block, COND_NE | OPCODE_B); + codegen_addlong(block, COND_NE | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BPL_(codeblock_t *block) +uint32_t * +host_arm_BPL_(codeblock_t *block) { - codegen_addlong(block, COND_PL | OPCODE_B); + codegen_addlong(block, COND_PL | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BVC_(codeblock_t *block) +uint32_t * +host_arm_BVC_(codeblock_t *block) { - codegen_addlong(block, COND_VC | OPCODE_B); + codegen_addlong(block, COND_VC | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BVS_(codeblock_t *block) +uint32_t * +host_arm_BVS_(codeblock_t *block) { - codegen_addlong(block, COND_VS | OPCODE_B); + codegen_addlong(block, COND_VS | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - fatal("host_arm_BEQ - out of range %08x %i\n", offset, offset); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + fatal("host_arm_BEQ - out of range %08x %i\n", offset, offset); - codegen_addlong(block, COND_EQ | OPCODE_B | B_OFFSET(offset)); + codegen_addlong(block, COND_EQ | OPCODE_B | B_OFFSET(offset)); } -void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); - codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); + codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); } -void host_arm_BX(codeblock_t *block, int addr_reg) +void +host_arm_BX(codeblock_t *block, int addr_reg) { - codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); + codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); } -void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm) +void +host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_CMP_IMM(block, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_CMN_IMM | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_CMN_REG_LSL(block, src_reg, REG_TEMP, 0); - } + if ((int32_t) imm < 0 && imm != 0x80000000) { + host_arm_CMP_IMM(block, src_reg, -(int32_t) imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_CMN_IMM | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_CMN_REG_LSL(block, src_reg, REG_TEMP, 0); + } } -void host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) +void +host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_CMN_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_CMN_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm) +void +host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_CMN_IMM(block, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_CMP_IMM | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_CMP_REG_LSL(block, src_reg, REG_TEMP, 0); - } + if ((int32_t) imm < 0 && imm != 0x80000000) { + host_arm_CMN_IMM(block, src_reg, -(int32_t) imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_CMP_IMM | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_CMP_REG_LSL(block, src_reg, REG_TEMP, 0); + } } -void host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) +void +host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_CMP_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_CMP_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) +void +host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { - codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); + codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); } -void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); } -void host_arm_LDR_IMM_POST(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_LDR_IMM_POST(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_LDR_IMM_POST | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_LDR_IMM_POST | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); } -void host_arm_LDR_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) +void +host_arm_LDR_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_LDR_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_LDR_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_LDRB_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_arm_LDRB_ABS(codeblock_t *block, int dst_reg, void *p) { - if (in_range(p, &cpu_state)) - host_arm_LDRB_IMM(block, dst_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("LDRB_ABS - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_LDRB_IMM(block, dst_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("LDRB_ABS - not in range\n"); } -void host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_LDRB_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_LDRB_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); } -void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) +void +host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_LDRB_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_LDRB_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_LDRH_IMM | Rn(addr_reg) | Rd(dst_reg) | LDRH_IMM(offset)); + codegen_addlong(block, COND_AL | OPCODE_LDRH_IMM | Rn(addr_reg) | Rd(dst_reg) | LDRH_IMM(offset)); } -void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg) +void +host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg) { - codegen_addlong(block, COND_AL | OPCODE_LDRH_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg)); + codegen_addlong(block, COND_AL | OPCODE_LDRH_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg)); } -void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) +void +host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); - } - else - { - host_arm_MOVW_IMM(block, dst_reg, imm & 0xffff); - if (imm >> 16) - host_arm_MOVT_IMM(block, dst_reg, imm >> 16); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); + } else { + host_arm_MOVW_IMM(block, dst_reg, imm & 0xffff); + if (imm >> 16) + host_arm_MOVT_IMM(block, dst_reg, imm >> 16); + } } -void host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_IMM(shift)); } -void host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +void +host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_REG(shift_reg)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_REG(shift_reg)); } -void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +void +host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_REG(shift_reg)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_REG(shift_reg)); } -void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); } -void host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +void +host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_REG(shift_reg)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_REG(shift_reg)); } -void host_arm_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_IMM(shift)); } -void host_arm_MOV_REG_ROR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +void +host_arm_MOV_REG_ROR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_REG(shift_reg)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_REG(shift_reg)); } -void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm) +void +host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm) { - codegen_addlong(block, COND_AL | OPCODE_MOVT_IMM | Rd(dst_reg) | MOVT_IMM(imm)); + codegen_addlong(block, COND_AL | OPCODE_MOVT_IMM | Rd(dst_reg) | MOVT_IMM(imm)); } -void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm) +void +host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm) { - codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm)); + codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm)); } -void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, cond | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_ORR_REG_LSL_cond(block, cond, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, cond | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_ORR_REG_LSL_cond(block, cond, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, cond | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, cond | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_RSB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_RSB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_RSB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_RSB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) +void +host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { - codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); + codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); } -void host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) +void +host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); } -void host_arm_STR_IMM_WB(codeblock_t *block, int src_reg, int addr_reg, int offset) +void +host_arm_STR_IMM_WB(codeblock_t *block, int src_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_STR_IMM_WB | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_STR_IMM_WB | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); } -void host_arm_STR_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) +void +host_arm_STR_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_STR_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_STR_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) +void +host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); } -void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) +void +host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_STRB_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_STRB_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_STRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_STRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_STRH_IMM | Rn(addr_reg) | Rd(dst_reg) | STRH_IMM(offset)); + codegen_addlong(block, COND_AL | OPCODE_STRH_IMM | Rn(addr_reg) | Rd(dst_reg) | STRH_IMM(offset)); } -void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg) +void +host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg) { - codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg)); + codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg)); } -void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if ((int32_t) imm < 0 && imm != 0x80000000) { + host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t) imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_SXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) +void +host_arm_SXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) { - codegen_addlong(block, OPCODE_SXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); + codegen_addlong(block, OPCODE_SXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_SXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) +void +host_arm_SXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) { - codegen_addlong(block, OPCODE_SXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); + codegen_addlong(block, OPCODE_SXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t imm) +void +host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_TST_IMM | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_TST_REG(block, src_reg, REG_TEMP); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_TST_IMM | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_TST_REG(block, src_reg, REG_TEMP); + } } -void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) +void +host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) { - codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); + codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); } -void host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void +host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); + codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void +host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); + codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void +host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); + codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void +host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); + codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) +void +host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) { - codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); + codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) +void +host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) { - codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); + codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VABS_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VABS_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VADD_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VADD_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VADD_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VADD_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VADD_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VADD_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VADD_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VADD_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VAND_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VAND_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VBIC_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VBIC_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) +void +host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); } -void host_arm_VCEQ_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCEQ_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCEQ_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCEQ_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCEQ_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCEQ_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCEQ_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCEQ_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCEQ_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCEQ_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCEQ_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCEQ_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGE_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGE_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGE_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGE_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGT_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGT_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGT_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGT_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGT_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGT_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGT_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGT_S32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGT_S32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_F32_S32(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_F32_S32(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_F32_S32 | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_F32_S32 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_IS_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_IS_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_S32_F32 | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_S32_F32 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVTR_IS_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVTR_IS_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VDIV_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VDIV_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VDIV_S | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VDIV_S | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VDUP_32(codeblock_t *block, int dst_reg, int src_reg_m, int imm) +void +host_arm_VDUP_32(codeblock_t *block, int dst_reg, int src_reg_m, int imm) { - codegen_addlong(block, COND_AL | OPCODE_VDUP_32 | Rd(dst_reg) | Rm(src_reg_m) | VDUP_32_IMM(imm)); + codegen_addlong(block, COND_AL | OPCODE_VDUP_32 | Rd(dst_reg) | Rm(src_reg_m) | VDUP_32_IMM(imm)); } -void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VEOR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VEOR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if ((offset > 1020) || (offset & 3)) - fatal("VLDR_D bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VLDR_D | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); + if ((offset > 1020) || (offset & 3)) + fatal("VLDR_D bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VLDR_D | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if ((offset > 1020) || (offset & 3)) - fatal("VLDR_S bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VLDR_S | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); + if ((offset > 1020) || (offset & 3)) + fatal("VLDR_S bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VLDR_S | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_32_S | Rt(dest_reg) | Vn(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_32_S | Rt(dest_reg) | Vn(src_reg)); } -void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg) +void +host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_64_D | Rt(dest_reg_low) | Rt2(dest_reg_high) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_64_D | Rt(dest_reg_low) | Rt2(dest_reg_high) | Vm(src_reg)); } -void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high) +void +host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_D_64 | Vm(dest_reg) | Rt(src_reg_low) | Rt2(src_reg_high)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_D_64 | Vm(dest_reg) | Rt(src_reg_low) | Rt2(src_reg_high)); } -void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_S_32 | Vn(dest_reg) | Rt(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_S_32 | Vn(dest_reg) | Rt(src_reg)); } -void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, OPCODE_VMOVN_I32 | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VMOVN_I32 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, OPCODE_VMOVN_I64 | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VMOVN_I64 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg) +void +host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_F32_ONE | Rd(dst_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_F32_ONE | Rd(dst_reg)); } -void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) +void +host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); } -void host_arm_VMRS_APSR(codeblock_t *block) +void +host_arm_VMRS_APSR(codeblock_t *block) { - codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR); + codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR); } -void host_arm_VMAX_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMAX_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VMAX_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VMAX_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMIN_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMIN_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VMIN_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VMIN_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMUL_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMUL_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VMUL_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VMUL_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMUL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMUL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VMUL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VMUL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VNEG_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VNEG_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VPADDL_S16 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VPADDL_S16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VPADDL_S32 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VPADDL_S32 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VPADDL_Q_S32(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VPADDL_Q_S32(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VPADDL_Q_S32 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VPADDL_Q_S32 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQADD_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQADD_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQADD_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQADD_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQADD_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQADD_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQADD_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQADD_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQSUB_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQSUB_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQSUB_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQSUB_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQSUB_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQSUB_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQSUB_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQSUB_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQSUB_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQMOVN_S16(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VQMOVN_S16(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VQMOVN_S16 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VQMOVN_S16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQMOVN_S32(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VQMOVN_S32(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VQMOVN_S32 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VQMOVN_S32 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VQMOVN_U16 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VQMOVN_U16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHL_D_IMM_16(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 15) - fatal("host_arm_VSHL_D_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHL_D_IMM_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + if (shift > 15) + fatal("host_arm_VSHL_D_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); } -void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHL_D_IMM_32(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 31) - fatal("host_arm_VSHL_D_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHL_D_IMM_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + if (shift > 31) + fatal("host_arm_VSHL_D_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); } -void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHL_D_IMM_64(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 63) - fatal("host_arm_VSHL_D_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHL_D_IMM_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + if (shift > 63) + fatal("host_arm_VSHL_D_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); } -void host_arm_VSHR_D_S16(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_S16(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 15) - fatal("host_arm_VSHR_SD_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHR_D_S16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift)); + if (shift > 15) + fatal("host_arm_VSHR_SD_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHR_D_S16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16 - shift)); } -void host_arm_VSHR_D_S32(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_S32(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 31) - fatal("host_arm_VSHR_SD_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHR_D_S32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift)); + if (shift > 31) + fatal("host_arm_VSHR_SD_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHR_D_S32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32 - shift)); } -void host_arm_VSHR_D_S64(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_S64(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 63) - fatal("host_arm_VSHR_SD_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHR_D_S64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift)); + if (shift > 63) + fatal("host_arm_VSHR_SD_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHR_D_S64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64 - shift)); } -void host_arm_VSHR_D_U16(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_U16(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 15) - fatal("host_arm_VSHR_UD_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHR_D_U16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift)); + if (shift > 15) + fatal("host_arm_VSHR_UD_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHR_D_U16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16 - shift)); } -void host_arm_VSHR_D_U32(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_U32(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 31) - fatal("host_arm_VSHR_UD_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHR_D_U32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift)); + if (shift > 31) + fatal("host_arm_VSHR_UD_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHR_D_U32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32 - shift)); } -void host_arm_VSHR_D_U64(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_U64(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 63) - fatal("host_arm_VSHR_UD_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHR_D_U64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift)); + if (shift > 63) + fatal("host_arm_VSHR_UD_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHR_D_U64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64 - shift)); } -void host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 16) - fatal("host_arm_VSHRN_32 : shift > 16\n"); - codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16-shift)); + if (shift > 16) + fatal("host_arm_VSHRN_32 : shift > 16\n"); + codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16 - shift)); } -void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VSQRT_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VSQRT_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VSQRT_S | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VSQRT_S | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) +void +host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { - if ((offset > 1020) || (offset & 3)) - fatal("VSTR_D bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VSTR_D | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); + if ((offset > 1020) || (offset & 3)) + fatal("VSTR_D bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VSTR_D | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset) +void +host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset) { - if ((offset > 1020) || (offset & 3)) - fatal("VSTR_S bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VSTR_S | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); + if ((offset > 1020) || (offset & 3)) + fatal("VSTR_S bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VSTR_S | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSUB_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VSUB_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VSUB_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VSUB_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VSUB_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VSUB_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VSUB_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg) +void +host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg) { - codegen_addlong(block, OPCODE_VZIP_D8 | Vd(d_reg) | Vm(m_reg)); + codegen_addlong(block, OPCODE_VZIP_D8 | Vd(d_reg) | Vm(m_reg)); } -void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg) +void +host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg) { - codegen_addlong(block, OPCODE_VZIP_D16 | Vd(d_reg) | Vm(m_reg)); + codegen_addlong(block, OPCODE_VZIP_D16 | Vd(d_reg) | Vm(m_reg)); } -void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg) +void +host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg) { - codegen_addlong(block, OPCODE_VZIP_D32 | Vd(d_reg) | Vm(m_reg)); + codegen_addlong(block, OPCODE_VZIP_D32 | Vd(d_reg) | Vm(m_reg)); } #endif diff --git a/src/codegen_new/codegen_backend_arm_ops.h b/src/codegen_new/codegen_backend_arm_ops.h index 7627f51a7..271fbffbd 100644 --- a/src/codegen_new/codegen_backend_arm_ops.h +++ b/src/codegen_new/codegen_backend_arm_ops.h @@ -1,19 +1,19 @@ #define COND_SHIFT 28 -#define COND_EQ (0x0 << COND_SHIFT) -#define COND_NE (0x1 << COND_SHIFT) -#define COND_CS (0x2 << COND_SHIFT) -#define COND_CC (0x3 << COND_SHIFT) -#define COND_MI (0x4 << COND_SHIFT) -#define COND_PL (0x5 << COND_SHIFT) -#define COND_VS (0x6 << COND_SHIFT) -#define COND_VC (0x7 << COND_SHIFT) -#define COND_HI (0x8 << COND_SHIFT) -#define COND_LS (0x9 << COND_SHIFT) -#define COND_GE (0xa << COND_SHIFT) -#define COND_LT (0xb << COND_SHIFT) -#define COND_GT (0xc << COND_SHIFT) -#define COND_LE (0xd << COND_SHIFT) -#define COND_AL (0xe << COND_SHIFT) +#define COND_EQ (0x0 << COND_SHIFT) +#define COND_NE (0x1 << COND_SHIFT) +#define COND_CS (0x2 << COND_SHIFT) +#define COND_CC (0x3 << COND_SHIFT) +#define COND_MI (0x4 << COND_SHIFT) +#define COND_PL (0x5 << COND_SHIFT) +#define COND_VS (0x6 << COND_SHIFT) +#define COND_VC (0x7 << COND_SHIFT) +#define COND_HI (0x8 << COND_SHIFT) +#define COND_LS (0x9 << COND_SHIFT) +#define COND_GE (0xa << COND_SHIFT) +#define COND_LT (0xb << COND_SHIFT) +#define COND_GT (0xc << COND_SHIFT) +#define COND_LE (0xd << COND_SHIFT) +#define COND_AL (0xe << COND_SHIFT) void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); #define host_arm_ADD_REG(block, dst_reg, src_reg_n, src_reg_m) host_arm_ADD_REG_LSL(block, dst_reg, src_reg_n, src_reg_m, 0) @@ -101,12 +101,12 @@ void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shif void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm); void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift); -#define host_arm_ORR_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_AL, dst_reg, src_reg, imm) +#define host_arm_ORR_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_AL, dst_reg, src_reg, imm) #define host_arm_ORR_REG_LSL(block, dst_reg, src_reg_a, src_reg_b, shift) host_arm_ORR_REG_LSL_cond(block, COND_AL, dst_reg, src_reg_a, src_reg_b, shift) -#define host_arm_ORRCC_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_CC, dst_reg, src_reg, imm) -#define host_arm_ORREQ_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_EQ, dst_reg, src_reg, imm) -#define host_arm_ORRVS_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_VS, dst_reg, src_reg, imm) +#define host_arm_ORRCC_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_CC, dst_reg, src_reg, imm) +#define host_arm_ORREQ_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_EQ, dst_reg, src_reg, imm) +#define host_arm_ORRVS_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_VS, dst_reg, src_reg, imm) void host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); void host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c index 8b0990016..4cc0ff38d 100644 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ b/src/codegen_new/codegen_backend_arm_uops.c @@ -1,3502 +1,3375 @@ #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "x86.h" -#include "x87.h" -#include "386_common.h" -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm_defs.h" -#include "codegen_backend_arm_ops.h" -#include "codegen_ir_defs.h" +# include "x86.h" +# include "x87.h" +# include "386_common.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm_defs.h" +# include "codegen_backend_arm_ops.h" +# include "codegen_ir_defs.h" -static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) +static inline int +get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) { - int shift = 0; - if (!(imm_data & 0xffff)) - { - shift += 16; - imm_data >>= 16; - } - if (!(imm_data & 0xff)) - { - shift += 8; - imm_data >>= 8; - } - if (!(imm_data & 0xf)) - { - shift += 4; - imm_data >>= 4; - } - if (!(imm_data & 0x3)) - { - shift += 2; - imm_data >>= 2; - } - if (imm_data > 0xff) /*Note - should handle rotation round the word*/ - return 0; - *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); - return 1; -} - -static inline int in_range(void *addr, void *base) -{ - int diff = (uintptr_t)addr - (uintptr_t)base; - - if (diff < -4095 || diff > 4095) - return 0; - return 1; -} - -static inline int in_range_h(void *addr, void *base) -{ - int diff = (uintptr_t)addr - (uintptr_t)base; - - if (diff < 0 || diff > 255) - return 0; - return 1; -} - -void host_arm_call(codeblock_t *block, void *dst_addr) -{ - host_arm_MOV_IMM(block, REG_R3, (uintptr_t)dst_addr); - host_arm_BLX(block, REG_R3); -} - -void host_arm_nop(codeblock_t *block) -{ - host_arm_MOV_REG_LSL(block, REG_R0, REG_R0, 0); -} - -#define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0xf) - -#define REG_IS_L(size) (size == IREG_SIZE_L) -#define REG_IS_W(size) (size == IREG_SIZE_W) -#define REG_IS_B(size) (size == IREG_SIZE_B) -#define REG_IS_BH(size) (size == IREG_SIZE_BH) -#define REG_IS_D(size) (size == IREG_SIZE_D) -#define REG_IS_Q(size) (size == IREG_SIZE_Q) - -static int codegen_ADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, 8); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_AND_IMM(block, REG_TEMP, src_reg_b, 0x0000ff00); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); - } - else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - + int shift = 0; + if (!(imm_data & 0xffff)) { + shift += 16; + imm_data >>= 16; + } + if (!(imm_data & 0xff)) { + shift += 8; + imm_data >>= 8; + } + if (!(imm_data & 0xf)) { + shift += 4; + imm_data >>= 4; + } + if (!(imm_data & 0x3)) { + shift += 2; + imm_data >>= 2; + } + if (imm_data > 0xff) /*Note - should handle rotation round the word*/ return 0; + *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); + return 1; } -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) + +static inline int +in_range(void *addr, void *base) { -// host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); -// return 0; - - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg) - { - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data << 8); - host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP); - } - else - fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + int diff = (uintptr_t) addr - (uintptr_t) base; + if (diff < -4095 || diff > 4095) return 0; - + return 1; } -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) + +static inline int +in_range_h(void *addr, void *base) { - host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + int diff = (uintptr_t) addr - (uintptr_t) base; + + if (diff < 0 || diff > 255) return 0; + return 1; } -static int codegen_AND(codeblock_t *block, uop_t *uop) +void +host_arm_call(codeblock_t *block, void *dst_addr) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VAND_D(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_AND_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); - host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 24); - host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); - host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 8); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); - host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 0); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); - host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ANDN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VBIC_D(block, dest_reg, src_reg_b, src_reg_a); - } - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; + host_arm_MOV_IMM(block, REG_R3, (uintptr_t) dst_addr); + host_arm_BLX(block, REG_R3); } -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +void +host_arm_nop(codeblock_t *block) { - host_arm_call(block, uop->p); - - return 0; + host_arm_MOV_REG_LSL(block, REG_R0, REG_R0, 0); } -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); +# define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0xf) - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); - host_arm_call(block, uop->p); +# define REG_IS_L(size) (size == IREG_SIZE_L) +# define REG_IS_W(size) (size == IREG_SIZE_W) +# define REG_IS_B(size) (size == IREG_SIZE_B) +# define REG_IS_BH(size) (size == IREG_SIZE_BH) +# define REG_IS_D(size) (size == IREG_SIZE_D) +# define REG_IS_Q(size) (size == IREG_SIZE_Q) + +static int +codegen_ADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, 8); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_AND_IMM(block, REG_TEMP, src_reg_b, 0x0000ff00); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +{ + // host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + // return 0; + + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg) { + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data << 8); + host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP); + } else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +{ + host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + return 0; +} + +static int +codegen_AND(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VAND_D(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_AND_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 24); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 8); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); + host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 0); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); + host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_AND_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VBIC_D(block, dest_reg, src_reg_b, src_reg_a); + } else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm_call(block, uop->p); + + return 0; +} + +static int +codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_arm_call(block, uop->p); + host_arm_MOV_REG(block, dest_reg, REG_R0); + + return 0; +} + +static int +codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm_call(block, uop->p); + host_arm_TST_REG(block, REG_R0, REG_R0); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; +} + +static int +codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_arm_BEQ(block, (uintptr_t) uop->p); + + return 0; +} + +static int +codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} +static int +codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} + +static int +codegen_CMP_JB(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); + + jump_p = host_arm_BCC_(block); + *jump_p |= ((((uintptr_t) uop->p - (uintptr_t) jump_p) - 8) & 0x3fffffc) >> 2; + + return 0; +} +static int +codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + + jump_p = host_arm_BHI_(block); + *jump_p |= ((((uintptr_t) uop->p - (uintptr_t) jump_p) - 8) & 0x3fffffc) >> 2; + + return 0; +} + +static int +codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BCS_(block); + + return 0; +} +static int +codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BHI_(block); + + return 0; +} +static int +codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BGE_(block); + + return 0; +} +static int +codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BGT_(block); + + return 0; +} +static int +codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BVC_(block); + + return 0; +} +static int +codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} +static int +codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BCC_(block); + + return 0; +} +static int +codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLS_(block); + + return 0; +} +static int +codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLT_(block); + + return 0; +} +static int +codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLE_(block); + + return 0; +} +static int +codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BVS_(block); + + return 0; +} +static int +codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} + +static int +codegen_FABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VABS_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_FCHS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VNEG_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_FSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VSQRT_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_FTST(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VSUB_D(block, REG_D_TEMP, REG_D_TEMP, REG_D_TEMP); + host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP); + host_arm_MOV_IMM(block, dest_reg, 0); + host_arm_VMRS_APSR(block); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3); + } else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_FADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VADD_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_FCOM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VCMP_D(block, src_reg_a, src_reg_b); + host_arm_MOV_IMM(block, dest_reg, 0); + host_arm_VMRS_APSR(block); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3); + } else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_FDIV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VDIV_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_FMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VMUL_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VSUB_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_ptr; + + if (!in_range(&cr0, &cpu_state)) + fatal("codegen_FP_ENTER - out of range\n"); + + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cr0 - (uintptr_t) &cpu_state); + host_arm_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm_BEQ_(block); + + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.oldpc - (uintptr_t) &cpu_state); + host_arm_MOV_IMM(block, REG_ARG0, 7); + host_arm_call(block, x86_int); + host_arm_B(block, (uintptr_t) codegen_exit_rout); + + *branch_ptr |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_ptr) - 8) & 0x3fffffc) >> 2; + + return 0; +} +static int +codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_ptr; + + if (!in_range(&cr0, &cpu_state)) + fatal("codegen_MMX_ENTER - out of range\n"); + + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cr0 - (uintptr_t) &cpu_state); + host_arm_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm_BEQ_(block); + + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.oldpc - (uintptr_t) &cpu_state); + host_arm_MOV_IMM(block, REG_ARG0, 7); + host_arm_call(block, x86_int); + host_arm_B(block, (uintptr_t) codegen_exit_rout); + + *branch_ptr |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_ptr) - 8) & 0x3fffffc) >> 2; + + host_arm_MOV_IMM(block, REG_TEMP, 0x01010101); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[0] - (uintptr_t) &cpu_state); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[4] - (uintptr_t) &cpu_state); + host_arm_MOV_IMM(block, REG_TEMP, 0); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); + host_arm_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); + + return 0; +} + +static int +codegen_JMP(codeblock_t *block, uop_t *uop) +{ + host_arm_B(block, (uintptr_t) uop->p); + + return 0; +} + +static int +codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_ARG0, src_reg, 0); + } else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + + return 0; +} +static int +codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; +} +static int +codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; +} +static int +codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; +} + +static int +codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); + return 0; +} +static int +codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data); + return 0; +} +static int +codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data); + return 0; +} +static int +codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data); + return 0; +} + +static int +codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + host_arm_UXTH(block, REG_ARG0, src_reg, 0); + host_arm_MOV_IMM(block, REG_ARG1, (uint32_t) uop->p); + host_arm_call(block, loadseg); + host_arm_TST_REG(block, REG_R0, REG_R0); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_long); + } else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 16); + } else if (REG_IS_L(dest_size)) { host_arm_MOV_REG(block, dest_reg, REG_R0); + } - return 0; + return 0; } -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - host_arm_call(block, uop->p); - host_arm_TST_REG(block, REG_R0, REG_R0); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - return 0; + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_quad); + } else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm_MOV_REG(block, dest_reg, REG_R0); + } else if (REG_IS_Q(dest_size)) { + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } + + return 0; +} +static int +codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_load_single); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + host_arm_VCVT_D_S(block, dest_reg, REG_D_TEMP); + + return 0; +} +static int +codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_load_double); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + + return 0; } -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size)) - { - host_arm_CMP_IMM(block, src_reg, uop->imm_data); - } - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); - host_arm_BEQ(block, (uintptr_t)uop->p); + host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_long); + } else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); - return 0; + return 0; } -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (REG_IS_L(src_size)) - { - host_arm_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_byte); + } else if (REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_R1, src_reg, 8); + host_arm_BL(block, (uintptr_t) codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_quad); + } else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); - uop->p = host_arm_BNE_(block); - - return 0; -} -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BEQ_(block); - - return 0; + return 0; } -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_store_byte); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); - jump_p = host_arm_BCC_(block); - *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; - - return 0; + return 0; } -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_store_word); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); - jump_p = host_arm_BHI_(block); - *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; + return 0; +} +static int +codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - return 0; + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_store_long); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_VCVT_S_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_single); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_double); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; } -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_MOV(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSL(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_BFI(block, dest_reg, src_reg, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_BFI(block, dest_reg, src_reg, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) { + host_arm_BFI(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_arm_VMOV_D_D(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_arm_VMOV_D_D(block, dest_reg, src_reg); + } else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - uop->p = host_arm_BCS_(block); - - return 0; -} -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BHI_(block); - - return 0; -} -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BGE_(block); - - return 0; -} -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BGT_(block); - - return 0; -} -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BVC_(block); - - return 0; -} -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BNE_(block); - - return 0; -} -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BCC_(block); - - return 0; -} -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BLS_(block); - - return 0; -} -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BLT_(block); - - return 0; -} -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BLE_(block); - - return 0; -} -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BVS_(block); - - return 0; -} -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BEQ_(block); - - return 0; + return 0; } -static int codegen_FABS(codeblock_t *block, uop_t *uop) +static int +codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VABS_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size)) { + host_arm_MOV_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_arm_MOVW_IMM(block, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size)) { + host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x000000ff); + host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size)) { + host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x0000ff00); + host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data << 8); + } else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); - return 0; + return 0; } -static int codegen_FCHS(codeblock_t *block, uop_t *uop) +static int +codegen_MOV_PTR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + host_arm_MOV_IMM(block, uop->dest_reg_a_real, (uintptr_t) uop->p); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VNEG_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VSQRT_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FTST(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VSUB_D(block, REG_D_TEMP, REG_D_TEMP, REG_D_TEMP); - host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP); - host_arm_MOV_IMM(block, dest_reg, 0); - host_arm_VMRS_APSR(block); - host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0|C2|C3); - } - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; + return 0; } -static int codegen_FADD(codeblock_t *block, uop_t *uop) +static int +codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VADD_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm_SXTB(block, dest_reg, src_reg, 0); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm_SXTB(block, dest_reg, src_reg, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm_SXTH(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_arm_SXTB(block, REG_TEMP, src_reg, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm_SXTB(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_FCOM(codeblock_t *block, uop_t *uop) +static int +codegen_MOVZX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VCMP_D(block, src_reg_a, src_reg_b); - host_arm_MOV_IMM(block, dest_reg, 0); - host_arm_VMRS_APSR(block); - host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0|C2|C3); - } - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FDIV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VDIV_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VMUL_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VSUB_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_ptr; - - if (!in_range(&cr0, &cpu_state)) - fatal("codegen_FP_ENTER - out of range\n"); - - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm_BEQ_(block); - - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm_MOV_IMM(block, REG_ARG0, 7); - host_arm_call(block, x86_int); - host_arm_B(block, (uintptr_t)codegen_exit_rout); - - *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; - - return 0; -} -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_ptr; - - if (!in_range(&cr0, &cpu_state)) - fatal("codegen_MMX_ENTER - out of range\n"); - - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm_BEQ_(block); - - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm_MOV_IMM(block, REG_ARG0, 7); - host_arm_call(block, x86_int); - host_arm_B(block, (uintptr_t)codegen_exit_rout); - - *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; - - host_arm_MOV_IMM(block, REG_TEMP, 0x01010101); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_IMM(block, REG_TEMP, 0); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); - - return 0; -} - -static int codegen_JMP(codeblock_t *block, uop_t *uop) -{ - host_arm_B(block, (uintptr_t)uop->p); - - return 0; -} - -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_ARG0, src_reg, 0); + host_arm_VMOV_D_64(block, dest_reg, src_reg, REG_TEMP); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_arm_VMOV_32_S(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, dest_reg, src_reg, 0); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, dest_reg, src_reg, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + if (src_reg == dest_reg) + host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); + else { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); } + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static double +int64_to_double(int64_t a) +{ + return (double) a; +} +static int +codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_arm_VMOV_S_32(block, REG_D_TEMP, src_reg); + host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_arm_SXTH(block, REG_TEMP, src_reg, 0); + host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP); + host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + /*ARMv7 has no instructions to convert a 64-bit integer to a double. + For simplicity, call a C function and let the compiler do it.*/ + host_arm_VMOV_64_D(block, REG_R0, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) int64_to_double); /*Input - R0/R1, Output - D0*/ + host_arm_VMOV_D_D(block, dest_reg, REG_D0); + } else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_fp_round); + host_arm_VMOV_32_S(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_fp_round); + host_arm_VMOV_32_S(block, REG_TEMP, REG_D_TEMP); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int64_t +x87_fround64(double b) +{ + int64_t a, c; + + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int64_t) floor(b); + c = (int64_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) floor(b); + case 2: /*Up*/ + return (int64_t) ceil(b); + case 3: /*Chop*/ + return (int64_t) b; + } + + return 0; +} +static int +codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_arm_VMOV_D_D(block, dest_reg, src_64_reg); + host_arm_TST_IMM(block, tag_reg, TAG_UINT64); + branch_offset = host_arm_BNE_(block); + + /*VFP/NEON has no instructions to convert a float to 64-bit integer, + so call out to C.*/ + host_arm_VMOV_D_D(block, REG_D0, src_reg); + host_arm_call(block, x87_fround64); + host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); + + *branch_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 8) & 0x3fffffc) >> 2; + } else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm_LDR_IMM(block, dest_reg, REG_TEMP, 0); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm_LDRB_IMM(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size)) { + host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm_LDRH_IMM(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int +codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + +static int +codegen_OR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VORR_D(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_ORR_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int +codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_S16(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_S16(block, REG_D_TEMP, REG_Q_TEMP_2); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_S32(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_S32(block, REG_D_TEMP, REG_Q_TEMP_2); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_U16(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_U16(block, REG_D_TEMP, REG_Q_TEMP_2); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_I8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_I16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_I32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_S8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_U8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_U16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_I8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_I16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_I32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_S8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_S32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm_VCVT_S32_F32(block, dest_reg, src_reg_a); + } else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGE_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMAX_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMIN_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMUL_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRECPE/VRECPS)*/ + host_arm_VMOV_F32_ONE(block, REG_D_TEMP); + host_arm_VDIV_S(block, dest_reg, REG_D_TEMP, src_reg_a); + host_arm_VDUP_32(block, dest_reg, dest_reg, 0); + } else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ + host_arm_VSQRT_S(block, REG_D_TEMP, src_reg_a); + host_arm_VMOV_F32_ONE(block, REG_D_TEMP); + host_arm_VDIV_S(block, dest_reg, dest_reg, REG_D_TEMP); + host_arm_VDUP_32(block, dest_reg, dest_reg, 0); + } else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm_VCVT_F32_S32(block, dest_reg, src_reg_a); + } else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int +codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); + host_arm_VPADDL_Q_S32(block, REG_Q_TEMP, REG_Q_TEMP); + host_arm_VMOVN_I64(block, dest_reg, REG_Q_TEMP); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); + host_arm_VSHRN_32(block, dest_reg, REG_Q_TEMP, 16); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + host_arm_VSHL_D_IMM_16(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +static int +codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); - return 0; -} -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); - return 0; -} -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); - return 0; -} + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data); - return 0; -} - -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); - host_arm_UXTH(block, REG_ARG0, src_reg, 0); - host_arm_MOV_IMM(block, REG_ARG1, (uint32_t)uop->p); - host_arm_call(block, loadseg); - host_arm_TST_REG(block, REG_R0, REG_R0); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_long); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm_MOV_REG(block, dest_reg, REG_R0); - } + host_arm_VSHL_D_IMM_32(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } - -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +static int +codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_quad); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm_MOV_REG(block, dest_reg, REG_R0); - } - else if (REG_IS_Q(dest_size)) - { - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } + host_arm_VSHL_D_IMM_64(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_load_single); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - host_arm_VCVT_D_S(block, dest_reg, REG_D_TEMP); - - return 0; -} -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_load_double); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - - return 0; -} - -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - - host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_long); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm_VSHR_D_S16(block, dest_reg, src_reg, 15); else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + host_arm_VSHR_D_S16(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } - -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - } - else if (REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_R1, src_reg, 8); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_quad); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm_VSHR_D_S32(block, dest_reg, src_reg, 31); else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + host_arm_VSHR_D_S32(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } - -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_store_word); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_store_long); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_VCVT_S_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_single); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_double); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MOV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSL(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_BFI(block, dest_reg, src_reg, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_BFI(block, dest_reg, src_reg, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) - { - host_arm_BFI(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_arm_VMOV_D_D(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_arm_VMOV_D_D(block, dest_reg, src_reg); - } - else - fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_arm_MOV_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_arm_MOVW_IMM(block, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size)) - { - host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x000000ff); - host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size)) - { - host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x0000ff00); - host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data << 8); - } - else - fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, uop->dest_reg_a_real, (uintptr_t)uop->p); - - return 0; -} - -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm_SXTB(block, dest_reg, src_reg, 0); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SXTB(block, dest_reg, src_reg, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm_SXTH(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_arm_SXTB(block, REG_TEMP, src_reg, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SXTB(block, REG_TEMP, src_reg, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_IMM(block, REG_TEMP, 0); - host_arm_VMOV_D_64(block, dest_reg, src_reg, REG_TEMP); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_arm_VMOV_32_S(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, dest_reg, src_reg, 0); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, dest_reg, src_reg, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - if (src_reg == dest_reg) - host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static double int64_to_double(int64_t a) -{ - return (double)a; -} -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_arm_VMOV_S_32(block, REG_D_TEMP, src_reg); - host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_arm_SXTH(block, REG_TEMP, src_reg, 0); - host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP); - host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - /*ARMv7 has no instructions to convert a 64-bit integer to a double. - For simplicity, call a C function and let the compiler do it.*/ - host_arm_VMOV_64_D(block, REG_R0, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)int64_to_double); /*Input - R0/R1, Output - D0*/ - host_arm_VMOV_D_D(block, dest_reg, REG_D0); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm_VSHR_D_S64(block, dest_reg, src_reg, 63); else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm_VSHR_D_S64(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_fp_round); - host_arm_VMOV_32_S(block, dest_reg, REG_D_TEMP); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_fp_round); - host_arm_VMOV_32_S(block, REG_TEMP, REG_D_TEMP); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm_VSHR_D_U16(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int64_t x87_fround64(double b) +static int +codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { - int64_t a, c; + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - } - - return 0; -} -static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_arm_VMOV_D_D(block, dest_reg, src_64_reg); - host_arm_TST_IMM(block, tag_reg, TAG_UINT64); - branch_offset = host_arm_BNE_(block); - - /*VFP/NEON has no instructions to convert a float to 64-bit integer, - so call out to C.*/ - host_arm_VMOV_D_D(block, REG_D0, src_reg); - host_arm_call(block, x87_fround64); - host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); - - *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm_VSHR_D_U32(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm_LDR_IMM(block, dest_reg, REG_TEMP, 0); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + host_arm_VSHR_D_U64(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; -} -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm_LDRB_IMM(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size)) - { - host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm_LDRH_IMM(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - - return 0; + return 0; } -static int codegen_NOP(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBB(codeblock_t *block, uop_t *uop) { - return 0; + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_I8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_I16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_I32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_S8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_U8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_U16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; } -static int codegen_OR(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VORR_D(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_ORR_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; +} +static int +codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; } -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +static int +codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); - host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); - host_arm_VQMOVN_S16(block, dest_reg, REG_Q_TEMP); - host_arm_VQMOVN_S16(block, REG_D_TEMP, REG_Q_TEMP_2); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - } - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 32); + host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, REG_TEMP2); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 16); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_ROR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +static int +codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); - host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); - host_arm_VQMOVN_S32(block, dest_reg, REG_Q_TEMP); - host_arm_VQMOVN_S32(block, REG_D_TEMP, REG_Q_TEMP_2); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm_MOV_REG(block, dest_reg, src_reg); + } else { + host_arm_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); } - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); - host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); - host_arm_VQMOVN_U16(block, dest_reg, REG_Q_TEMP); - host_arm_VQMOVN_U16(block, REG_D_TEMP, REG_Q_TEMP_2); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) + host_arm_BFI(block, dest_reg, src_reg, 0, 16); + } else { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16 - (uop->imm_data & 15)); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); } - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PADDB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_I8(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + host_arm_BFI(block, dest_reg, src_reg, 0, 8); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); } - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_I16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_I32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_S8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_U8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_U16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_I8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_I16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_I32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_S8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_S32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm_VCVT_S32_F32(block, dest_reg, src_reg_a); - } - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGE_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMAX_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMIN_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMUL_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRECPE/VRECPS)*/ - host_arm_VMOV_F32_ONE(block, REG_D_TEMP); - host_arm_VDIV_S(block, dest_reg, REG_D_TEMP, src_reg_a); - host_arm_VDUP_32(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ - host_arm_VSQRT_S(block, REG_D_TEMP, src_reg_a); - host_arm_VMOV_F32_ONE(block, REG_D_TEMP); - host_arm_VDIV_S(block, dest_reg, dest_reg, REG_D_TEMP); - host_arm_VDUP_32(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm_VCVT_F32_S32(block, dest_reg, src_reg_a); - } - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); - host_arm_VPADDL_Q_S32(block, REG_Q_TEMP, REG_Q_TEMP); - host_arm_VMOVN_I64(block, dest_reg, REG_Q_TEMP); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); - host_arm_VSHRN_32(block, dest_reg, REG_Q_TEMP, 16); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHL_D_IMM_16(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHL_D_IMM_32(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHL_D_IMM_64(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm_VSHR_D_S16(block, dest_reg, src_reg, 15); - else - host_arm_VSHR_D_S16(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm_VSHR_D_S32(block, dest_reg, src_reg, 31); - else - host_arm_VSHR_D_S32(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm_VSHR_D_S64(block, dest_reg, src_reg, 63); - else - host_arm_VSHR_D_S64(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHR_D_U16(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHR_D_U32(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHR_D_U64(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_I8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_I16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_I32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_S8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_U8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_U16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 32); - host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, REG_TEMP2); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 16); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_ROR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm_MOV_REG(block, dest_reg, src_reg); - } - else - { - host_arm_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); - } - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - host_arm_BFI(block, dest_reg, src_reg, 0, 16); - } - else - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16-(uop->imm_data & 15)); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - host_arm_BFI(block, dest_reg, src_reg, 0, 8); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ROR(codeblock_t *block, uop_t *uop) +static int +codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 15); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 15); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm_MOV_REG(block, dest_reg, src_reg); - } - else - { - host_arm_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm_MOV_REG(block, dest_reg, src_reg); + } else { + host_arm_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SAR(codeblock_t *block, uop_t *uop) +static int +codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_ASR_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); - host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_ASR_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); - host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHL(codeblock_t *block, uop_t *uop) +static int +codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSL_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSL_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSL_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSL(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSL(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHR(codeblock_t *block, uop_t *uop) +static int +codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSR_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSR_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { - host_arm_MOV_IMM(block, REG_R0, uop->imm_data); + host_arm_MOV_IMM(block, REG_R0, uop->imm_data); - if (in_range(uop->p, &cpu_state)) - host_arm_STR_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); + if (in_range(uop->p, &cpu_state)) + host_arm_STR_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t) uop->p - (uintptr_t) &cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); - return 0; + return 0; } -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +static int +codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) { - host_arm_MOV_IMM(block, REG_R0, uop->imm_data); - if (in_range(uop->p, &cpu_state)) - host_arm_STRB_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); + host_arm_MOV_IMM(block, REG_R0, uop->imm_data); + if (in_range(uop->p, &cpu_state)) + host_arm_STRB_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t) uop->p - (uintptr_t) &cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); - return 0; + return 0; } -static int codegen_SUB(codeblock_t *block, uop_t *uop) +static int +codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_SUB_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); - host_arm_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_SUB_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; -// host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); -// return 0; + // host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + // return 0; } -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm_BEQ_(block); + uop->p = host_arm_BEQ_(block); - return 0; + return 0; } -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm_BNE_(block); + uop->p = host_arm_BNE_(block); - return 0; + return 0; } -static int codegen_XOR(codeblock_t *block, uop_t *uop) +static int +codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VEOR_D(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VEOR_D(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, +const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & + UOP_MASK] + = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & + UOP_MASK] + = codegen_CALL_INSTRUCTION_FUNC, - [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_JMP & + UOP_MASK] + = codegen_JMP, - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_SEG & + UOP_MASK] + = codegen_LOAD_SEG, - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3, - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + [UOP_LOAD_FUNC_ARG_0_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3_IMM, - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_STORE_P_IMM & + UOP_MASK] + = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & + UOP_MASK] + = codegen_STORE_PTR_IMM_8, - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, + [UOP_MEM_LOAD_ABS & + UOP_MASK] + = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & + UOP_MASK] + = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & + UOP_MASK] + = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & + UOP_MASK] + = codegen_MEM_LOAD_DOUBLE, - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, + [UOP_MEM_STORE_ABS & + UOP_MASK] + = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & + UOP_MASK] + = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & + UOP_MASK] + = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & + UOP_MASK] + = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & + UOP_MASK] + = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & + UOP_MASK] + = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & + UOP_MASK] + = codegen_MEM_STORE_DOUBLE, - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + [UOP_MOV & + UOP_MASK] + = codegen_MOV, + [UOP_MOV_PTR & + UOP_MASK] + = codegen_MOV_PTR, + [UOP_MOV_IMM & + UOP_MASK] + = codegen_MOV_IMM, + [UOP_MOVSX & + UOP_MASK] + = codegen_MOVSX, + [UOP_MOVZX & + UOP_MASK] + = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & + UOP_MASK] + = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & + UOP_MASK] + = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & + UOP_MASK] + = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & + UOP_MASK] + = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_16, - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + [UOP_ADD & + UOP_MASK] + = codegen_ADD, + [UOP_ADD_IMM & + UOP_MASK] + = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & + UOP_MASK] + = codegen_ADD_LSHIFT, + [UOP_AND & + UOP_MASK] + = codegen_AND, + [UOP_AND_IMM & + UOP_MASK] + = codegen_AND_IMM, + [UOP_ANDN & + UOP_MASK] + = codegen_ANDN, + [UOP_OR & + UOP_MASK] + = codegen_OR, + [UOP_OR_IMM & + UOP_MASK] + = codegen_OR_IMM, + [UOP_SUB & + UOP_MASK] + = codegen_SUB, + [UOP_SUB_IMM & + UOP_MASK] + = codegen_SUB_IMM, + [UOP_XOR & + UOP_MASK] + = codegen_XOR, + [UOP_XOR_IMM & + UOP_MASK] + = codegen_XOR_IMM, - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, + [UOP_SAR & + UOP_MASK] + = codegen_SAR, + [UOP_SAR_IMM & + UOP_MASK] + = codegen_SAR_IMM, + [UOP_SHL & + UOP_MASK] + = codegen_SHL, + [UOP_SHL_IMM & + UOP_MASK] + = codegen_SHL_IMM, + [UOP_SHR & + UOP_MASK] + = codegen_SHR, + [UOP_SHR_IMM & + UOP_MASK] + = codegen_SHR_IMM, + [UOP_ROL & + UOP_MASK] + = codegen_ROL, + [UOP_ROL_IMM & + UOP_MASK] + = codegen_ROL_IMM, + [UOP_ROR & + UOP_MASK] + = codegen_ROR, + [UOP_ROR_IMM & + UOP_MASK] + = codegen_ROR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_IMM_JZ & + UOP_MASK] + = codegen_CMP_IMM_JZ, - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JB & + UOP_MASK] + = codegen_CMP_JB, + [UOP_CMP_JNBE & + UOP_MASK] + = codegen_CMP_JNBE, - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + [UOP_CMP_JNB_DEST & + UOP_MASK] + = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & + UOP_MASK] + = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & + UOP_MASK] + = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & + UOP_MASK] + = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & + UOP_MASK] + = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & + UOP_MASK] + = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & + UOP_MASK] + = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & + UOP_MASK] + = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & + UOP_MASK] + = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & + UOP_MASK] + = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & + UOP_MASK] + = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & + UOP_MASK] + = codegen_CMP_JZ_DEST, - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + [UOP_CMP_IMM_JNZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JZ_DEST, - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + [UOP_TEST_JNS_DEST & + UOP_MASK] + = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & + UOP_MASK] + = codegen_TEST_JS_DEST, - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, + [UOP_FP_ENTER & + UOP_MASK] + = codegen_FP_ENTER, + [UOP_MMX_ENTER & + UOP_MASK] + = codegen_MMX_ENTER, - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FADD & + UOP_MASK] + = codegen_FADD, + [UOP_FCOM & + UOP_MASK] + = codegen_FCOM, + [UOP_FDIV & + UOP_MASK] + = codegen_FDIV, + [UOP_FMUL & + UOP_MASK] + = codegen_FMUL, + [UOP_FSUB & + UOP_MASK] + = codegen_FSUB, - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, + [UOP_FABS & + UOP_MASK] + = codegen_FABS, + [UOP_FCHS & + UOP_MASK] + = codegen_FCHS, + [UOP_FSQRT & + UOP_MASK] + = codegen_FSQRT, + [UOP_FTST & + UOP_MASK] + = codegen_FTST, - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PACKSSWB & + UOP_MASK] + = codegen_PACKSSWB, + [UOP_PACKSSDW & + UOP_MASK] + = codegen_PACKSSDW, + [UOP_PACKUSWB & + UOP_MASK] + = codegen_PACKUSWB, - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PADDB & + UOP_MASK] + = codegen_PADDB, + [UOP_PADDW & + UOP_MASK] + = codegen_PADDW, + [UOP_PADDD & + UOP_MASK] + = codegen_PADDD, + [UOP_PADDSB & + UOP_MASK] + = codegen_PADDSB, + [UOP_PADDSW & + UOP_MASK] + = codegen_PADDSW, + [UOP_PADDUSB & + UOP_MASK] + = codegen_PADDUSB, + [UOP_PADDUSW & + UOP_MASK] + = codegen_PADDUSW, - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PCMPEQB & + UOP_MASK] + = codegen_PCMPEQB, + [UOP_PCMPEQW & + UOP_MASK] + = codegen_PCMPEQW, + [UOP_PCMPEQD & + UOP_MASK] + = codegen_PCMPEQD, + [UOP_PCMPGTB & + UOP_MASK] + = codegen_PCMPGTB, + [UOP_PCMPGTW & + UOP_MASK] + = codegen_PCMPGTW, + [UOP_PCMPGTD & + UOP_MASK] + = codegen_PCMPGTD, - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PF2ID & + UOP_MASK] + = codegen_PF2ID, + [UOP_PFADD & + UOP_MASK] + = codegen_PFADD, + [UOP_PFCMPEQ & + UOP_MASK] + = codegen_PFCMPEQ, + [UOP_PFCMPGE & + UOP_MASK] + = codegen_PFCMPGE, + [UOP_PFCMPGT & + UOP_MASK] + = codegen_PFCMPGT, + [UOP_PFMAX & + UOP_MASK] + = codegen_PFMAX, + [UOP_PFMIN & + UOP_MASK] + = codegen_PFMIN, + [UOP_PFMUL & + UOP_MASK] + = codegen_PFMUL, + [UOP_PFRCP & + UOP_MASK] + = codegen_PFRCP, + [UOP_PFRSQRT & + UOP_MASK] + = codegen_PFRSQRT, + [UOP_PFSUB & + UOP_MASK] + = codegen_PFSUB, + [UOP_PI2FD & + UOP_MASK] + = codegen_PI2FD, - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PMADDWD & + UOP_MASK] + = codegen_PMADDWD, + [UOP_PMULHW & + UOP_MASK] + = codegen_PMULHW, + [UOP_PMULLW & + UOP_MASK] + = codegen_PMULLW, - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSLLW_IMM & + UOP_MASK] + = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & + UOP_MASK] + = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & + UOP_MASK] + = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & + UOP_MASK] + = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & + UOP_MASK] + = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & + UOP_MASK] + = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & + UOP_MASK] + = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & + UOP_MASK] + = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & + UOP_MASK] + = codegen_PSRLQ_IMM, - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + [UOP_PSUBB & + UOP_MASK] + = codegen_PSUBB, + [UOP_PSUBW & + UOP_MASK] + = codegen_PSUBW, + [UOP_PSUBD & + UOP_MASK] + = codegen_PSUBD, + [UOP_PSUBSB & + UOP_MASK] + = codegen_PSUBSB, + [UOP_PSUBSW & + UOP_MASK] + = codegen_PSUBSW, + [UOP_PSUBUSB & + UOP_MASK] + = codegen_PSUBUSB, + [UOP_PSUBUSW & + UOP_MASK] + = codegen_PSUBUSW, - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + [UOP_PUNPCKHBW & + UOP_MASK] + = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & + UOP_MASK] + = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & + UOP_MASK] + = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & + UOP_MASK] + = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & + UOP_MASK] + = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & + UOP_MASK] + = codegen_PUNPCKLDQ, - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP + [UOP_NOP_BARRIER & + UOP_MASK] + = codegen_NOP }; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - if (in_range_h(p, &cpu_state)) - host_arm_LDRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_8 - not in range\n"); + if (in_range_h(p, &cpu_state)) + host_arm_LDRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_8 - not in range\n"); } -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - if (in_range_h(p, &cpu_state)) - host_arm_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - { - host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); - host_arm_LDRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); - } + if (in_range_h(p, &cpu_state)) + host_arm_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else { + host_arm_MOV_IMM(block, REG_R3, (uintptr_t) p - (uintptr_t) &cpu_state); + host_arm_LDRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); + } } -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - if (in_range(p, &cpu_state)) - host_arm_LDR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_32 - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_LDR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_32 - not in range\n"); } -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - codegen_direct_read_32(block, host_reg, p); + codegen_direct_read_32(block, host_reg, p); } -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); } -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); } -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_LDRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_LDRB_IMM(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - if (in_range(p, &cpu_state)) - host_arm_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_8 - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_8 - not in range\n"); } -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - if (in_range_h(p, &cpu_state)) - host_arm_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - { - host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); - host_arm_STRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); - } + if (in_range_h(p, &cpu_state)) + host_arm_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else { + host_arm_MOV_IMM(block, REG_R3, (uintptr_t) p - (uintptr_t) &cpu_state); + host_arm_STRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); + } } -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - if (in_range(p, &cpu_state)) - host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_32 - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_32 - not in range\n"); } -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); } -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - if (in_range(p, &cpu_state)) - host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_ptr - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_ptr - not in range\n"); } -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (stack_offset >= 0 && stack_offset < 256) - host_arm_LDRH_IMM(block, host_reg, REG_HOST_SP, stack_offset); - else - fatal("codegen_direct_read_32 - not in range\n"); + if (stack_offset >= 0 && stack_offset < 256) + host_arm_LDRH_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_read_32 - not in range\n"); } -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (stack_offset >= 0 && stack_offset < 4096) - host_arm_LDR_IMM(block, host_reg, REG_HOST_SP, stack_offset); - else - fatal("codegen_direct_read_32 - not in range\n"); + if (stack_offset >= 0 && stack_offset < 4096) + host_arm_LDR_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_read_32 - not in range\n"); } -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - codegen_direct_read_32_stack(block, host_reg, stack_offset); + codegen_direct_read_32_stack(block, host_reg, stack_offset); } -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); + host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); } -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); + host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); } -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - if (stack_offset >= 0 && stack_offset < 4096) - host_arm_STR_IMM(block, host_reg, REG_HOST_SP, stack_offset); - else - fatal("codegen_direct_write_32 - not in range\n"); + if (stack_offset >= 0 && stack_offset < 4096) + host_arm_STR_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_write_32 - not in range\n"); } -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); + host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); } -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); + host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); } -void codegen_set_jump_dest(codeblock_t *block, void *p) +void +codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)p) - 8) & 0x3fffffc) >> 2; + *(uint32_t *) p |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) p) - 8) & 0x3fffffc) >> 2; } #endif diff --git a/src/codegen_new/codegen_backend_x86-64.c b/src/codegen_new/codegen_backend_x86-64.c index 8411ca8da..a57cb4282 100644 --- a/src/codegen_new/codegen_backend_x86-64.c +++ b/src/codegen_new/codegen_backend_x86-64.c @@ -1,28 +1,28 @@ #if defined __amd64__ || defined _M_X64 -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86-64_defs.h" -#include "codegen_backend_x86-64_ops.h" -#include "codegen_backend_x86-64_ops_sse.h" -#include "codegen_reg.h" -#include "x86.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86-64_defs.h" +# include "codegen_backend_x86-64_ops.h" +# include "codegen_backend_x86-64_ops_sse.h" +# include "codegen_reg.h" +# include "x86.h" -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#include -#endif -#include +# if defined(__linux__) || defined(__APPLE__) +# include +# include +# endif +# if defined WIN32 || defined _WIN32 || defined _WIN32 +# include +# endif +# include void *codegen_mem_load_byte; void *codegen_mem_load_word; @@ -41,346 +41,338 @@ void *codegen_mem_store_double; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - /*Note: while EAX and EDX are normally volatile registers under x86 - calling conventions, the recompiler will explicitly save and restore - them across funcion calls*/ - {REG_EAX, 0}, - {REG_EBX, 0}, - {REG_EDX, 0} +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + /*Note: while EAX and EDX are normally volatile registers under x86 + calling conventions, the recompiler will explicitly save and restore + them across funcion calls*/ + {REG_EAX, 0}, + { REG_EBX, 0}, + { REG_EDX, 0} }; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ -#if _WIN64 - /*Windows x86-64 calling convention preserves XMM6-XMM15*/ - {REG_XMM6, 0}, - {REG_XMM7, 0}, -#else - /*System V AMD64 calling convention does not preserve any XMM registers*/ - {REG_XMM6, HOST_REG_FLAG_VOLATILE}, - {REG_XMM7, HOST_REG_FLAG_VOLATILE}, -#endif - {REG_XMM1, HOST_REG_FLAG_VOLATILE}, - {REG_XMM2, HOST_REG_FLAG_VOLATILE}, - {REG_XMM3, HOST_REG_FLAG_VOLATILE}, - {REG_XMM4, HOST_REG_FLAG_VOLATILE}, - {REG_XMM5, HOST_REG_FLAG_VOLATILE} +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { +# if _WIN64 + /*Windows x86-64 calling convention preserves XMM6-XMM15*/ + {REG_XMM6, 0 }, + { REG_XMM7, 0 }, +# else + /*System V AMD64 calling convention does not preserve any XMM registers*/ + { REG_XMM6, HOST_REG_FLAG_VOLATILE }, + { REG_XMM7, HOST_REG_FLAG_VOLATILE }, +# endif + { REG_XMM1, HOST_REG_FLAG_VOLATILE}, + { REG_XMM2, HOST_REG_FLAG_VOLATILE}, + { REG_XMM3, HOST_REG_FLAG_VOLATILE}, + { REG_XMM4, HOST_REG_FLAG_VOLATILE}, + { REG_XMM5, HOST_REG_FLAG_VOLATILE} }; -static void build_load_routine(codeblock_t *block, int size, int is_float) +static void +build_load_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *branch_offset; + uint8_t *misaligned_offset; - /*In - ESI = address - Out - ECX = data, ESI = abrt*/ - /*MOV ECX, ESI - SHR ESI, 12 - MOV RSI, [readlookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOVZX ECX, B[RSI+RCX] - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL readmembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV64_REG_IMM(block, REG_RDI, (uint64_t)(uintptr_t)readlookup2); - host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_RDI, REG_RSI, 3); - if (size != 1) - { - host_x86_TEST32_REG_IMM(block, REG_ECX, size-1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 2 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 4 && !is_float) - host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 4 && is_float) - host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); - else if (size == 8) - host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); - else - fatal("build_load_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ESI = address + Out - ECX = data, ESI = abrt*/ + /*MOV ECX, ESI + SHR ESI, 12 + MOV RSI, [readlookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOVZX ECX, B[RSI+RCX] + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL readmembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV64_REG_IMM(block, REG_RDI, (uint64_t) (uintptr_t) readlookup2); + host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_RDI, REG_RSI, 3); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_ECX, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t) -1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 2 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 4 && !is_float) + host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 4 && is_float) + host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); + else if (size == 8) + host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); + else + fatal("build_load_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - host_x86_PUSH(block, REG_RAX); - host_x86_PUSH(block, REG_RDX); -#if _WIN64 - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); - //host_x86_MOV32_REG_REG(block, REG_ECX, uop->imm_data); -#else - host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); -#endif - if (size == 1 && !is_float) - { - host_x86_CALL(block, (void *)readmembl); - host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); - } - else if (size == 2 && !is_float) - { - host_x86_CALL(block, (void *)readmemwl); - host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); - } - else if (size == 4 && !is_float) - { - host_x86_CALL(block, (void *)readmemll); - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - } - else if (size == 4 && is_float) - { - host_x86_CALL(block, (void *)readmemll); - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); - host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - } - else if (size == 8) - { - host_x86_CALL(block, (void *)readmemql); - host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX); - } -#if _WIN64 - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); -#endif - host_x86_POP(block, REG_RDX); - host_x86_POP(block, REG_RAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); + *branch_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 1; + host_x86_PUSH(block, REG_RAX); + host_x86_PUSH(block, REG_RDX); +# if _WIN64 + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); + // host_x86_MOV32_REG_REG(block, REG_ECX, uop->imm_data); +# else + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); +# endif + if (size == 1 && !is_float) { + host_x86_CALL(block, (void *) readmembl); + host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); + } else if (size == 2 && !is_float) { + host_x86_CALL(block, (void *) readmemwl); + host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); + } else if (size == 4 && !is_float) { + host_x86_CALL(block, (void *) readmemll); + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + } else if (size == 4 && is_float) { + host_x86_CALL(block, (void *) readmemll); + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + } else if (size == 8) { + host_x86_CALL(block, (void *) readmemql); + host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX); + } +# if _WIN64 + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); +# endif + host_x86_POP(block, REG_RDX); + host_x86_POP(block, REG_RAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); } -static void build_store_routine(codeblock_t *block, int size, int is_float) +static void +build_store_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *branch_offset; + uint8_t *misaligned_offset; - /*In - ECX = data, ESI = address - Out - ESI = abrt - Corrupts EDI*/ - /*MOV EDI, ESI - SHR ESI, 12 - MOV ESI, [writelookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOV [RSI+RDI], ECX - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL writemembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV64_REG_IMM(block, REG_R8, (uint64_t)(uintptr_t)writelookup2); - host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_R8, REG_RSI, 3); - if (size != 1) - { - host_x86_TEST32_REG_IMM(block, REG_EDI, size-1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOV8_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 2 && !is_float) - host_x86_MOV16_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 4 && !is_float) - host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 4 && is_float) - host_x86_MOVD_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); - else if (size == 8) - host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); - else - fatal("build_store_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ECX = data, ESI = address + Out - ESI = abrt + Corrupts EDI*/ + /*MOV EDI, ESI + SHR ESI, 12 + MOV ESI, [writelookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOV [RSI+RDI], ECX + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL writemembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV64_REG_IMM(block, REG_R8, (uint64_t) (uintptr_t) writelookup2); + host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_R8, REG_RSI, 3); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_EDI, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t) -1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOV8_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 2 && !is_float) + host_x86_MOV16_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 4 && !is_float) + host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 4 && is_float) + host_x86_MOVD_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); + else if (size == 8) + host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); + else + fatal("build_store_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - host_x86_PUSH(block, REG_RAX); - host_x86_PUSH(block, REG_RDX); -#if _WIN64 - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x28); - if (size == 4 && is_float) - host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); //data - else if (size == 8) - host_x86_MOVQ_REG_XREG(block, REG_RDX, REG_XMM_TEMP); //data - else - host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); //address -#else - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x8); - //host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address - if (size == 4 && is_float) - host_x86_MOVD_REG_XREG(block, REG_ESI, REG_XMM_TEMP); //data - else if (size == 8) - host_x86_MOVQ_REG_XREG(block, REG_RSI, REG_XMM_TEMP); //data - else - host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); //data -#endif - if (size == 1) - host_x86_CALL(block, (void *)writemembl); - else if (size == 2) - host_x86_CALL(block, (void *)writememwl); - else if (size == 4) - host_x86_CALL(block, (void *)writememll); - else if (size == 8) - host_x86_CALL(block, (void *)writememql); -#if _WIN64 - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x28); -#else - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x8); -#endif - host_x86_POP(block, REG_RDX); - host_x86_POP(block, REG_RAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); + *branch_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 1; + host_x86_PUSH(block, REG_RAX); + host_x86_PUSH(block, REG_RDX); +# if _WIN64 + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x28); + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); // data + else if (size == 8) + host_x86_MOVQ_REG_XREG(block, REG_RDX, REG_XMM_TEMP); // data + else + host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); // data + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); // address +# else + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x8); + // host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_ESI, REG_XMM_TEMP); // data + else if (size == 8) + host_x86_MOVQ_REG_XREG(block, REG_RSI, REG_XMM_TEMP); // data + else + host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); // data +# endif + if (size == 1) + host_x86_CALL(block, (void *) writemembl); + else if (size == 2) + host_x86_CALL(block, (void *) writememwl); + else if (size == 4) + host_x86_CALL(block, (void *) writememll); + else if (size == 8) + host_x86_CALL(block, (void *) writememql); +# if _WIN64 + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x28); +# else + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x8); +# endif + host_x86_POP(block, REG_RDX); + host_x86_POP(block, REG_RAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); } -static void build_loadstore_routines(codeblock_t *block) +static void +build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } -void codegen_backend_init() +void +codegen_backend_init(void) { - codeblock_t *block; - int c; + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL, block_current); - codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block); - block_write_data = codeblock[block_current].data; - build_loadstore_routines(&codeblock[block_current]); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL, block_current); + codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block); + block_write_data = codeblock[block_current].data; + build_loadstore_routines(&codeblock[block_current]); - codegen_gpf_rout = &codeblock[block_current].data[block_pos]; -#if _WIN64 - host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX); - host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX); -#else - host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); -#endif - host_x86_CALL(block, (void *)x86gpf); - codegen_exit_rout = &codeblock[block_current].data[block_pos]; - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); - host_x86_POP(block, REG_R15); - host_x86_POP(block, REG_R14); - host_x86_POP(block, REG_R13); - host_x86_POP(block, REG_R12); - host_x86_POP(block, REG_RDI); - host_x86_POP(block, REG_RSI); - host_x86_POP(block, REG_RBP); - host_x86_POP(block, REG_RDX); - host_x86_RET(block); + codegen_gpf_rout = &codeblock[block_current].data[block_pos]; +# if _WIN64 + host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX); + host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX); +# else + host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); +# endif + host_x86_CALL(block, (void *) x86gpf); + codegen_exit_rout = &codeblock[block_current].data[block_pos]; + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); + host_x86_POP(block, REG_R15); + host_x86_POP(block, REG_R14); + host_x86_POP(block, REG_R13); + host_x86_POP(block, REG_R12); + host_x86_POP(block, REG_RDI); + host_x86_POP(block, REG_RSI); + host_x86_POP(block, REG_RBP); + host_x86_POP(block, REG_RDX); + host_x86_RET(block); - block_write_data = NULL; + block_write_data = NULL; - asm( - "stmxcsr %0\n" - : "=m" (cpu_state.old_fp_control) - ); - cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; + asm( + "stmxcsr %0\n" + : "=m"(cpu_state.old_fp_control)); + cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; } -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); + cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); } -void codegen_backend_prologue(codeblock_t *block) +void +codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; /*Entry code*/ - host_x86_PUSH(block, REG_RBX); - host_x86_PUSH(block, REG_RBP); - host_x86_PUSH(block, REG_RSI); - host_x86_PUSH(block, REG_RDI); - host_x86_PUSH(block, REG_R12); - host_x86_PUSH(block, REG_R13); - host_x86_PUSH(block, REG_R14); - host_x86_PUSH(block, REG_R15); - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x38); - host_x86_MOV64_REG_IMM(block, REG_RBP, ((uintptr_t)&cpu_state) + 128); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); - host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); - host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, IREG_TOP_diff_stack_offset, REG_EAX); - } - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - host_x86_MOV64_REG_IMM(block, REG_R12, (uintptr_t)ram); + block_pos = BLOCK_START; /*Entry code*/ + host_x86_PUSH(block, REG_RBX); + host_x86_PUSH(block, REG_RBP); + host_x86_PUSH(block, REG_RSI); + host_x86_PUSH(block, REG_RDI); + host_x86_PUSH(block, REG_R12); + host_x86_PUSH(block, REG_R13); + host_x86_PUSH(block, REG_R14); + host_x86_PUSH(block, REG_R15); + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x38); + host_x86_MOV64_REG_IMM(block, REG_RBP, ((uintptr_t) &cpu_state) + 128); + if (block->flags & CODEBLOCK_HAS_FPU) { + host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); + host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, IREG_TOP_diff_stack_offset, REG_EAX); + } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + host_x86_MOV64_REG_IMM(block, REG_R12, (uintptr_t) ram); } -void codegen_backend_epilogue(codeblock_t *block) +void +codegen_backend_epilogue(codeblock_t *block) { - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); - host_x86_POP(block, REG_R15); - host_x86_POP(block, REG_R14); - host_x86_POP(block, REG_R13); - host_x86_POP(block, REG_R12); - host_x86_POP(block, REG_RDI); - host_x86_POP(block, REG_RSI); - host_x86_POP(block, REG_RBP); - host_x86_POP(block, REG_RDX); - host_x86_RET(block); + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); + host_x86_POP(block, REG_R15); + host_x86_POP(block, REG_R14); + host_x86_POP(block, REG_R13); + host_x86_POP(block, REG_R12); + host_x86_POP(block, REG_RDI); + host_x86_POP(block, REG_RSI); + host_x86_POP(block, REG_RBP); + host_x86_POP(block, REG_RDX); + host_x86_RET(block); } #endif diff --git a/src/codegen_new/codegen_backend_x86-64.h b/src/codegen_new/codegen_backend_x86-64.h index ccc526b30..5f476010d 100644 --- a/src/codegen_new/codegen_backend_x86-64.h +++ b/src/codegen_new/codegen_backend_x86-64.h @@ -1,14 +1,14 @@ #include "codegen_backend_x86-64_defs.h" -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff #define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) -#define BLOCK_MAX 0x3c0 +#define BLOCK_MAX 0x3c0 #define CODEGEN_BACKEND_HAS_MOV_IMM diff --git a/src/codegen_new/codegen_backend_x86-64_defs.h b/src/codegen_new/codegen_backend_x86-64_defs.h index 8955773cd..12f05f01c 100644 --- a/src/codegen_new/codegen_backend_x86-64_defs.h +++ b/src/codegen_new/codegen_backend_x86-64_defs.h @@ -1,52 +1,52 @@ /*RBP = cpu_state + 128 R12 = ram (if block->flags & CODEBLOCK_NO_IMMEDIATES)*/ -#define REG_AX 0 -#define REG_CX 1 -#define REG_DX 2 -#define REG_BX 3 -#define REG_SP 4 -#define REG_BP 5 -#define REG_SI 6 -#define REG_DI 7 +#define REG_AX 0 +#define REG_CX 1 +#define REG_DX 2 +#define REG_BX 3 +#define REG_SP 4 +#define REG_BP 5 +#define REG_SI 6 +#define REG_DI 7 -#define REG_EAX 0 -#define REG_ECX 1 -#define REG_EDX 2 -#define REG_EBX 3 -#define REG_ESP 4 -#define REG_EBP 5 -#define REG_ESI 6 -#define REG_EDI 7 +#define REG_EAX 0 +#define REG_ECX 1 +#define REG_EDX 2 +#define REG_EBX 3 +#define REG_ESP 4 +#define REG_EBP 5 +#define REG_ESI 6 +#define REG_EDI 7 -#define REG_RAX 0 -#define REG_RCX 1 -#define REG_RDX 2 -#define REG_RBX 3 -#define REG_RSP 4 -#define REG_RBP 5 -#define REG_RSI 6 -#define REG_RDI 7 -#define REG_R8 8 -#define REG_R9 9 -#define REG_R10 10 -#define REG_R11 11 -#define REG_R12 12 -#define REG_R13 13 -#define REG_R14 14 -#define REG_R15 15 +#define REG_RAX 0 +#define REG_RCX 1 +#define REG_RDX 2 +#define REG_RBX 3 +#define REG_RSP 4 +#define REG_RBP 5 +#define REG_RSI 6 +#define REG_RDI 7 +#define REG_R8 8 +#define REG_R9 9 +#define REG_R10 10 +#define REG_R11 11 +#define REG_R12 12 +#define REG_R13 13 +#define REG_R14 14 +#define REG_R15 15 -#define REG_XMM0 0 -#define REG_XMM1 1 -#define REG_XMM2 2 -#define REG_XMM3 3 -#define REG_XMM4 4 -#define REG_XMM5 5 -#define REG_XMM6 6 -#define REG_XMM7 7 +#define REG_XMM0 0 +#define REG_XMM1 1 +#define REG_XMM2 2 +#define REG_XMM3 3 +#define REG_XMM4 4 +#define REG_XMM5 5 +#define REG_XMM6 6 +#define REG_XMM7 7 -#define REG_XMM_TEMP REG_XMM0 +#define REG_XMM_TEMP REG_XMM0 -#define CODEGEN_HOST_REGS 3 +#define CODEGEN_HOST_REGS 3 #define CODEGEN_HOST_FP_REGS 7 extern void *codegen_mem_load_byte; diff --git a/src/codegen_new/codegen_backend_x86-64_ops.c b/src/codegen_new/codegen_backend_x86-64_ops.c index 2baa0f585..33fb500db 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops.c +++ b/src/codegen_new/codegen_backend_x86-64_ops.c @@ -1,1831 +1,1766 @@ #if defined __amd64__ || defined _M_X64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86-64_defs.h" -#include "codegen_backend_x86-64_ops.h" -#include "codegen_backend_x86-64_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86-64_defs.h" +# include "codegen_backend_x86-64_ops.h" +# include "codegen_backend_x86-64_ops_helpers.h" -#define RM_OP_ADD 0x00 -#define RM_OP_OR 0x08 -#define RM_OP_AND 0x20 -#define RM_OP_SUB 0x28 -#define RM_OP_XOR 0x30 -#define RM_OP_CMP 0x38 +# define RM_OP_ADD 0x00 +# define RM_OP_OR 0x08 +# define RM_OP_AND 0x20 +# define RM_OP_SUB 0x28 +# define RM_OP_XOR 0x30 +# define RM_OP_CMP 0x38 -#define RM_OP_ROL 0x00 -#define RM_OP_ROR 0x08 -#define RM_OP_SHL 0x20 -#define RM_OP_SHR 0x28 -#define RM_OP_SAR 0x38 +# define RM_OP_ROL 0x00 +# define RM_OP_ROR 0x08 +# define RM_OP_SHL 0x20 +# define RM_OP_SHR 0x28 +# define RM_OP_SAR 0x38 -static inline void call(codeblock_t *block, uintptr_t func) +static inline void +call(codeblock_t *block, uintptr_t func) { - intptr_t diff; + intptr_t diff; - codegen_alloc_bytes(block, 5); - diff = (intptr_t)(func - (uintptr_t)&block_write_data[block_pos + 5]); + codegen_alloc_bytes(block, 5); + diff = (intptr_t) (func - (uintptr_t) &block_write_data[block_pos + 5]); - if (diff >= -0x80000000LL && diff < 0x7fffffffLL) - { - codegen_addbyte(block, 0xE8); /*CALL*/ - codegen_addlong(block, (uint32_t)diff); - } - else - { - codegen_alloc_bytes(block, 13); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ - codegen_addquad(block, func); - codegen_addbyte3(block, 0x41, 0xff, 0xd1); /*CALL R9*/ - } + if (diff >= -0x80000000LL && diff < 0x7fffffffLL) { + codegen_addbyte(block, 0xE8); /*CALL*/ + codegen_addlong(block, (uint32_t) diff); + } else { + codegen_alloc_bytes(block, 13); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ + codegen_addquad(block, func); + codegen_addbyte3(block, 0x41, 0xff, 0xd1); /*CALL R9*/ + } } -static inline void jmp(codeblock_t *block, uintptr_t func) +static inline void +jmp(codeblock_t *block, uintptr_t func) { - intptr_t diff; + intptr_t diff; - codegen_alloc_bytes(block, 5); - diff = (intptr_t)(func - (uintptr_t)&block_write_data[block_pos + 5]); + codegen_alloc_bytes(block, 5); + diff = (intptr_t) (func - (uintptr_t) &block_write_data[block_pos + 5]); - if (diff >= -0x80000000LL && diff < 0x7fffffffLL) - { - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uint32_t)diff); - } - else - { - codegen_alloc_bytes(block, 13); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ - codegen_addquad(block, func); - codegen_addbyte3(block, 0x41, 0xff, 0xe1); /*JMP R9*/ - } + if (diff >= -0x80000000LL && diff < 0x7fffffffLL) { + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uint32_t) diff); + } else { + codegen_alloc_bytes(block, 13); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ + codegen_addquad(block, func); + codegen_addbyte3(block, 0x41, 0xff, 0xe1); /*JMP R9*/ + } } -void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_ADD8_REG_IMM - dst_reg & 8\n"); - - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ - } -} -void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_ADD16_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_ADD32_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_ADD64_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else - fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); -} -void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD8_REG_REG - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_ADD8_REG_IMM - dst_reg & 8\n"); + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ -} -void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD16_REG_REG - dst_reg & 8\n"); - + codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ + } } -void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD32_REG_REG - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_ADD16_REG_IMM - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ -} - -void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_AND8_REG_IMM - dst_reg & 8\n"); - - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ - } -} -void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_AND16_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_AND32_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND8_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ -} -void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND16_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ -} -void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND32_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ -} - -void host_x86_CALL(codeblock_t *block, void *p) -{ - call(block, (uintptr_t)p); -} - -void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else - fatal("CMP64_REG_IMM not 8-bit imm\n"); -} - -void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} -void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} -void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} - -void host_x86_JMP(codeblock_t *block, void *p) -{ - jmp(block, (uintptr_t)p); -} - -void host_x86_JNZ(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} -void host_x86_JZ(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} - -uint8_t *host_x86_JNZ_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x75, 0); /*JNZ*/ - return &block_write_data[block_pos-1]; -} -uint8_t *host_x86_JS_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x78, 0); /*JS*/ - return &block_write_data[block_pos-1]; -} -uint8_t *host_x86_JZ_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x74, 0); /*JZ*/ - return &block_write_data[block_pos-1]; -} - -uint32_t *host_x86_JNB_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNBE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNL_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNLE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNO_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNS_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNZ_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JB_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JBE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JL_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JLE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JO_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JS_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JZ_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} - -void host_x86_LAHF(codeblock_t *block) -{ - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x9f); /*LAHF*/ -} - -void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) -{ - if (offset) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ - codegen_addlong(block, offset); - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ - } -} -void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_LEA_REG_REG - bad reg\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b]*/ - ((src_reg_b & 7) << 3) | (src_reg_a & 7)); -} -void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) -{ - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ - (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); -} - -void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ - codegen_addbyte(block, imm_data); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); - codegen_alloc_bytes(block, 8); - codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addbyte(block, imm_data); - } -} -void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ - codegen_addword(block, imm_data); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); - codegen_alloc_bytes(block, 10); - codegen_addbyte4(block, 0x66, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addword(block, imm_data); - } -} -void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); - codegen_alloc_bytes(block, 11); - codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addlong(block, imm_data); - } -} - -void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV8_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV16_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ - codegen_addlong(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); - } -} -void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV32_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ - codegen_addlong(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV64_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} - -void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int index_reg, int shift, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } -} - -void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV B[base_reg + index_reg], src_reg*/ -} -void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV W[base_reg + index_reg], src_reg*/ -} -void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ -} - -void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - - if (dst_reg & 8) - fatal("host_x86_MOV8_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x41, 0x8a, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - fatal("host_x86_MOV8_REG_ABS - out of range\n"); - } -} -void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - - if (dst_reg & 8) - fatal("host_x86_MOV16_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3)); /*MOV dst_reg, ram_offset[R12]*/ - codegen_addbyte(block, 0x24); - codegen_addlong(block, ram_offset); - } - else - { - fatal("host_x86_MOV16_REG_ABS - out of range\n"); - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 1); - codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [r9]*/ - } -} -void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - - if (dst_reg & 8) - fatal("host_x86_MOV32_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - fatal("host_x86_MOV32_REG_ABS - out of range\n"); - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (dst_reg & 8) - fatal("host_x86_MOV64_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } - else - fatal("host_x86_MOV64_REG_ABS - out of range\n"); -} - -void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift) -{ - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n"); - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } -} - -void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg) -{ - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV32_REG_BASE_INDEX reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); /*MOV dst_reg, Q[base_reg + index_reg]*/ -} - -void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale) -{ - if ((dst_reg & 8) || (index_reg & 8)) - fatal("host_x86_MOV64_REG_BASE_INDEX_SHIFT reg & 8\n"); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 4); - if (base_reg & 8) - codegen_addbyte4(block, 0x49, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ - else - codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ -} - -void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV16_REG_BASE_OFFSET reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); -} -void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV32_REG_BASE_OFFSET reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); -} -void host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x48); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); -} - -void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV32_BASE_OFFSET_REG reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } - else - fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); -} -void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x48); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } - else - fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); -} - -void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) -{ - if (base_reg & 8) - fatal("host_x86_MOV32_BASE_OFFSET_IMM reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); - codegen_addlong(block, imm_data); - } - } - else - fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); -} - -void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) -{ - if (reg >= 8) - fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ -} -void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) -{ - if (reg & 8) - fatal("host_x86_MOV16_REG_IMM reg & 8\n"); - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ codegen_addword(block, imm_data); -} -void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) -{ - if (reg & 8) - fatal("host_x86_MOV32_REG_IMM reg & 8\n"); + } else { codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_ADD32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void +host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_ADD64_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else + fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); +} +void +host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD8_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ +} +void +host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD16_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ +} +void +host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD32_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) +void +host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (reg & 8) - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ - codegen_addquad(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ - codegen_addquad(block, imm_data); - } -} - -void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV8_REG_REG - bad reg\n"); + if (dst_reg & 8) + fatal("host_x86_AND8_REG_IMM - dst_reg & 8\n"); + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); -} -void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV16_REG_REG - bad reg\n"); - + codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ + } } -void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV32_REG_REG - bad reg\n"); + if (dst_reg & 8) + fatal("host_x86_AND16_REG_IMM - dst_reg & 8\n"); + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_AND32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void +host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND8_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ +} +void +host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND16_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ +} +void +host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND32_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ +} + +void +host_x86_CALL(codeblock_t *block, void *p) +{ + call(block, (uintptr_t) p); +} + +void +host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void +host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else + fatal("CMP64_REG_IMM not 8-bit imm\n"); +} + +void +host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void +host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void +host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} + +void +host_x86_JMP(codeblock_t *block, void *p) +{ + jmp(block, (uintptr_t) p); +} + +void +host_x86_JNZ(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} +void +host_x86_JZ(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} + +uint8_t * +host_x86_JNZ_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x75, 0); /*JNZ*/ + return &block_write_data[block_pos - 1]; +} +uint8_t * +host_x86_JS_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x78, 0); /*JS*/ + return &block_write_data[block_pos - 1]; +} +uint8_t * +host_x86_JZ_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x74, 0); /*JZ*/ + return &block_write_data[block_pos - 1]; +} + +uint32_t * +host_x86_JNB_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNBE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNL_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNLE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNO_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNS_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNZ_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JB_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JBE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JL_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JLE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JO_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JS_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JZ_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} + +void +host_x86_LAHF(codeblock_t *block) +{ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x9f); /*LAHF*/ +} + +void +host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) +{ + if (offset) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ + codegen_addlong(block, offset); + } else { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ + } +} +void +host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_LEA_REG_REG - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b]*/ + ((src_reg_b & 7) << 3) | (src_reg_a & 7)); +} +void +host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ + (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); } -void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) +void +host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - if (!offset) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else if (offset >= -0x80 && offset < 0x80) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 11); - codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, offset); - codegen_addlong(block, imm_data); - } -} + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ + codegen_addbyte(block, imm_data); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 8); + codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t) (uintptr_t) p); + codegen_addbyte(block, imm_data); + } } -void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ + codegen_addword(block, imm_data); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 10); + codegen_addbyte4(block, 0x66, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t) (uintptr_t) p); + codegen_addword(block, imm_data); + } } -void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 11); + codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t) (uintptr_t) p); + codegen_addlong(block, imm_data); + } } -void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +void +host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) { - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOVZX_BASE_INDEX_32_8 reg & 8\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + if (src_reg & 8) + fatal("host_x86_MOV8_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } +} +void +host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (src_reg & 8) + fatal("host_x86_MOV16_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); + codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ + codegen_addlong(block, offset); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + } } -void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +void +host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOVZX_BASE_INDEX_32_16 reg & 8\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); -} - -void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); - - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} -void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); + if (src_reg & 8) + fatal("host_x86_MOV32_ABS_REG - bad reg\n"); + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ + codegen_addlong(block, offset); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } } -void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + if (src_reg & 8) + fatal("host_x86_MOV64_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } +} + +void +host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int index_reg, int shift, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } +} + +void +host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV B[base_reg + index_reg], src_reg*/ +} +void +host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV W[base_reg + index_reg], src_reg*/ +} +void +host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ +} + +void +host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; + + if (dst_reg & 8) + fatal("host_x86_MOV8_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x41, 0x8a, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + fatal("host_x86_MOV8_REG_ABS - out of range\n"); + } } - -void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) +void +host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_16_8 - bad reg\n"); + if (dst_reg & 8) + fatal("host_x86_MOV16_REG_ABS reg & 8\n"); - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x66, 0x41); - codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ - } -} -void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - -// if (dst_reg & 8) -// fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - if (dst_reg & 8) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x44); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); - - codegen_alloc_bytes(block, 9); - codegen_addbyte(block, 0x41); - codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); - - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ - } -} -void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_32_16 - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 9); - codegen_addbyte(block, 0x41); - codegen_addbyte4(block, 0x0f, 0xb7, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x41, 0x0f, 0xb7, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ - } -} - -void host_x86_NOP(codeblock_t *block) -{ + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3)); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addbyte(block, 0x24); + codegen_addlong(block, ram_offset); + } else { + fatal("host_x86_MOV16_REG_ABS - out of range\n"); + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t) p); codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x90); /*NOP*/ + codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [r9]*/ + } } - -void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - if (dst_reg & 8) - fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ - } -} -void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ -} -void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_MOV32_REG_ABS reg & 8\n"); + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ + codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + fatal("host_x86_MOV32_REG_ABS - out of range\n"); + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } } -void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ + if (dst_reg & 8) + fatal("host_x86_MOV64_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else + fatal("host_x86_MOV64_REG_ABS - out of range\n"); } -void host_x86_POP(codeblock_t *block, int dst_reg) +void +host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift) { + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n"); + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } +} + +void +host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV32_REG_BASE_INDEX reg & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); /*MOV dst_reg, Q[base_reg + index_reg]*/ +} + +void +host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale) +{ + if ((dst_reg & 8) || (index_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_INDEX_SHIFT reg & 8\n"); + codegen_alloc_bytes(block, 4); + if (base_reg & 8) + codegen_addbyte4(block, 0x49, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ + else + codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ +} + +void +host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV16_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); +} +void +host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV32_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} +void +host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} + +void +host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV32_BASE_OFFSET_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); +} +void +host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); +} + +void +host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) +{ + if (base_reg & 8) + fatal("host_x86_MOV32_BASE_OFFSET_IMM reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); + codegen_addlong(block, imm_data); + } + } else + fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); +} + +void +host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) +{ + if (reg >= 8) + fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ +} +void +host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) +{ + if (reg & 8) + fatal("host_x86_MOV16_REG_IMM reg & 8\n"); + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); +} +void +host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) +{ + if (reg & 8) + fatal("host_x86_MOV32_REG_IMM reg & 8\n"); + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); +} + +void +host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) +{ + if (reg & 8) { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ + codegen_addquad(block, imm_data); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ + codegen_addquad(block, imm_data); + } +} + +void +host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV8_REG_REG - bad reg\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} +void +host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV16_REG_REG - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} +void +host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV32_REG_REG - bad reg\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} + +void +host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) +{ + if (!offset) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else if (offset >= -0x80 && offset < 0x80) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 11); + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } +} + +void +host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void +host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void +host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} + +void +host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOVZX_BASE_INDEX_32_8 reg & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); +} +void +host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOVZX_BASE_INDEX_32_16 reg & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); +} + +void +host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void +host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void +host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} + +void +host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; + + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_16_8 - bad reg\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x66, 0x41); + codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t) p); + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } +} +void +host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; + + // if (dst_reg & 8) + // fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + + if (offset >= -128 && offset < 127) { + if (dst_reg & 8) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x44); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { if (dst_reg & 8) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x41, 0x58 | (dst_reg & 7)); /*POP reg*/ - } - else - { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x58 | dst_reg); /*POP reg*/ - } + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + + codegen_alloc_bytes(block, 9); + codegen_addbyte(block, 0x41); + codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t) p); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } +} +void +host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; + + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_16 - bad reg\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 9); + codegen_addbyte(block, 0x41); + codegen_addbyte4(block, 0x0f, 0xb7, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t) p); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x41, 0x0f, 0xb7, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } } -void host_x86_PUSH(codeblock_t *block, int src_reg) +void +host_x86_NOP(codeblock_t *block) { - if (src_reg & 8) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x41, 0x50 | (src_reg & 7)); /*PUSH reg*/ - } - else - { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ - } + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x90); /*NOP*/ } -void host_x86_RET(codeblock_t *block) +void +host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { + if (dst_reg & 8) + fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); + + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ + } +} +void +host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void +host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ +} +void +host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ +} +void +host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ +} + +void +host_x86_POP(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x41, 0x58 | (dst_reg & 7)); /*POP reg*/ + } else { codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0xc3); /*RET*/ + codegen_addbyte(block, 0x58 | dst_reg); /*POP reg*/ + } } -void host_x86_ROL8_CL(codeblock_t *block, int dst_reg) +void +host_x86_PUSH(codeblock_t *block, int src_reg) { - if (dst_reg & 8) - fatal("ROL8 CL & 8\n"); + if (src_reg & 8) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_ROL16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROL16 CL & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_ROL32_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROL32 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + codegen_addbyte2(block, 0x41, 0x50 | (src_reg & 7)); /*PUSH reg*/ + } else { + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ + } } -void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_RET(codeblock_t *block) { - if (dst_reg & 8) - fatal("ROL8 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0xc3); /*RET*/ } -void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) + +void +host_x86_ROL8_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("ROL16 imm & 8\n"); + if (dst_reg & 8) + fatal("ROL8 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_ROL16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROL16 CL & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_ROL32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROL32 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} + +void +host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROL8 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROL16 imm & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROL32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void +host_x86_ROR8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROR8 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_ROR16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROR16 CL & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_ROR32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROR32 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} + +void +host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROR8 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROR16 imm & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROR32 im & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +void +host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SAR8 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void +host_x86_SAR16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SAR16 CL & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void +host_x86_SAR32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SAR32 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} + +void +host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SAR8 imm & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void +host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SAR16 imm & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void +host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SAR32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} + +void +host_x86_SHL8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHL8 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_SHL16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHL16 CL & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_SHL32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHL32 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} + +void +host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHL8 imm & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHL16 imm & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHL32 imm & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void +host_x86_SHR8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHR8 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_SHR16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHR16 CL & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_SHR32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHR32 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} + +void +host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHR8 imm & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHR16 imm & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHR32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +void +host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_SUB8_REG_IMM - dst_reg & 8\n"); + + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ + } +} +void +host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_SUB16_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("ROL32 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ -} - -void host_x86_ROR8_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROR8 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_ROR16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROR16 CL & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_ROR32_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROR32 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} - -void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("ROR8 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("ROR16 imm & 8\n"); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("ROR32 im & 8\n"); + if (dst_reg & 8) + fatal("host_x86_SUB32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } - -void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +void +host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) { - if (dst_reg & 8) - fatal("SAR8 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} -void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SAR16 CL & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} -void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SAR32 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} - -void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SAR8 imm & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ -} -void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SAR16 imm & 8\n"); + if (dst_reg & 8) + fatal("host_x86_SUB64_REG_IMM - dst_reg & 8\n"); + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else + fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); } -void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg & 8) - fatal("SAR32 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB8_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ +} +void +host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB16_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ +} +void +host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB32_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHL8 CL & 8\n"); +# define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) +void +host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_TEST32_REG - bad reg\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg & 8) + fatal("TEST32_REG_IMM reg & 8\n"); + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void +host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); + + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHL16 CL & 8\n"); - + codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ + } } -void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) +void +host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg & 8) - fatal("SHL32 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ -} - -void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHL8 imm & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHL16 imm & 8\n"); + if (dst_reg & 8) + fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHL32 imm & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} - -void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHR8 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHR16 CL & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHR32 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} - -void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHR8 imm & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHR16 imm & 8\n"); - + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("SHR32 imm & 8\n"); + if (dst_reg & 8) + fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } - -void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg & 8) - fatal("host_x86_SUB8_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } -void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +void +host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg & 8) - fatal("host_x86_SUB16_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } -void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +void +host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg & 8) - fatal("host_x86_SUB32_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_SUB64_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else - fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); -} -void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB8_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ -} -void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB16_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ -} -void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB32_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ -} - -#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) - -void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_TEST32_REG - bad reg\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("TEST32_REG_IMM reg & 8\n"); - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); - - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ - } -} -void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ -} -void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ -} -void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } #endif diff --git a/src/codegen_new/codegen_backend_x86-64_ops_helpers.h b/src/codegen_new/codegen_backend_x86-64_ops_helpers.h index a7755d1a8..42c2d5259 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops_helpers.h +++ b/src/codegen_new/codegen_backend_x86-64_ops_helpers.h @@ -1,102 +1,103 @@ #define JMP_LEN_BYTES 5 -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +static inline void +codegen_addbyte(codeblock_t *block, uint8_t val) { - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte over! %i\n", block_pos); -// CPU_BLOCK_END(); - } - block_write_data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) { + fatal("codegen_addbyte over! %i\n", block_pos); + // CPU_BLOCK_END(); + } + block_write_data[block_pos++] = val; } -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +static inline void +codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) { - if (block_pos > (BLOCK_MAX-2)) - { - fatal("codegen_addbyte2 over! %i\n", block_pos); - CPU_BLOCK_END(); - } - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; + if (block_pos > (BLOCK_MAX - 2)) { + fatal("codegen_addbyte2 over! %i\n", block_pos); + CPU_BLOCK_END(); + } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; } -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +static inline void +codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) { - if (block_pos > (BLOCK_MAX-3)) - { - fatal("codegen_addbyte3 over! %i\n", block_pos); - CPU_BLOCK_END(); - } - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; + if (block_pos > (BLOCK_MAX - 3)) { + fatal("codegen_addbyte3 over! %i\n", block_pos); + CPU_BLOCK_END(); + } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; } -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +static inline void +codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { - if (block_pos > (BLOCK_MAX-4)) - { - fatal("codegen_addbyte4 over! %i\n", block_pos); - CPU_BLOCK_END(); - } - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; - block_write_data[block_pos++] = vald; + if (block_pos > (BLOCK_MAX - 4)) { + fatal("codegen_addbyte4 over! %i\n", block_pos); + CPU_BLOCK_END(); + } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; + block_write_data[block_pos++] = vald; } -static inline void codegen_addword(codeblock_t *block, uint16_t val) +static inline void +codegen_addword(codeblock_t *block, uint16_t val) { - if (block_pos > (BLOCK_MAX-2)) - { - fatal("codegen_addword over! %i\n", block_pos); - CPU_BLOCK_END(); - } - *(uint16_t *)&block_write_data[block_pos] = val; - block_pos += 2; + if (block_pos > (BLOCK_MAX - 2)) { + fatal("codegen_addword over! %i\n", block_pos); + CPU_BLOCK_END(); + } + *(uint16_t *) &block_write_data[block_pos] = val; + block_pos += 2; } -static inline void codegen_addlong(codeblock_t *block, uint32_t val) +static inline void +codegen_addlong(codeblock_t *block, uint32_t val) { - if (block_pos > (BLOCK_MAX-4)) - { - fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; + if (block_pos > (BLOCK_MAX - 4)) { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } + *(uint32_t *) &block_write_data[block_pos] = val; + block_pos += 4; } -static inline void codegen_addquad(codeblock_t *block, uint64_t val) +static inline void +codegen_addquad(codeblock_t *block, uint64_t val) { - if (block_pos > (BLOCK_MAX-8)) - { - fatal("codegen_addquad over! %i\n", block_pos); - CPU_BLOCK_END(); - } - *(uint64_t *)&block_write_data[block_pos] = val; - block_pos += 8; + if (block_pos > (BLOCK_MAX - 8)) { + fatal("codegen_addquad over! %i\n", block_pos); + CPU_BLOCK_END(); + } + *(uint64_t *) &block_write_data[block_pos] = val; + block_pos += 8; } -static inline void codegen_alloc_bytes(codeblock_t *block, int size) +static inline void +codegen_alloc_bytes(codeblock_t *block, int size) { - if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) - { - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) { + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - /*Add a jump instruction to the new block*/ - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); + /*Add a jump instruction to the new block*/ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t) new_ptr - (uintptr_t) &block_write_data[block_pos + 4]); - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; - } + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; + } } -static inline int is_imm8(uint32_t imm_data) +static inline int +is_imm8(uint32_t imm_data) { - if (imm_data <= 0x7f || imm_data >= 0xffffff80) - return 1; - return 0; + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; } diff --git a/src/codegen_new/codegen_backend_x86-64_ops_sse.c b/src/codegen_new/codegen_backend_x86-64_ops_sse.c index e2a4e7044..f15b1aee4 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops_sse.c +++ b/src/codegen_new/codegen_backend_x86-64_ops_sse.c @@ -1,618 +1,678 @@ #if defined __amd64__ || defined _M_X64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86-64_defs.h" -#include "codegen_backend_x86-64_ops_sse.h" -#include "codegen_backend_x86-64_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86-64_defs.h" +# include "codegen_backend_x86-64_ops_sse.h" +# include "codegen_backend_x86-64_ops_helpers.h" -void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ } -void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ +} + +void +host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); +} + +void +host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ +} +void +host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ +} + +void +host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ +} +void +host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); +} +void +host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} +void +host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} +void +host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} +void +host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} + +void +host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); +} +void +host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ +} + +void +host_x86_LDMXCSR(codeblock_t *block, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ + codegen_addlong(block, offset); + } else { + fatal("host_x86_LDMXCSR - out of range %p\n", p); + } } -void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +void +host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ } -void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +void +host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); +} +void +host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ -} -void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ -} -void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ + if (src_reg & 8) + fatal("host_x86_MOVQ_ABS_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ -} -void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ -} -void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} - -void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ -} - -void host_x86_LDMXCSR(codeblock_t *block, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ - codegen_addlong(block, offset); - } - else - { - fatal("host_x86_LDMXCSR - out of range %p\n", p); - } -} - -void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ -} - -void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOVQ_ABS_REG reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addbyte(block, 0x25); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) -{ - if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); - - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} - -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); -} - -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (dst_reg & 8) - fatal("host_x86_MOVQ_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addbyte(block, 0x25); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) -{ - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); - - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); -} - -void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ -} - -void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ -} -void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ -} - -void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ -} -void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } } -void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) { + if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); + + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } -void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) + +void +host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); +} + +void +host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOVQ_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } } +void +host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); -void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ -} -void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ -} -void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ -} -void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ -} -void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ -} - -void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ -} -void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ -} -void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ -} -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ -} - -void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ -} -void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ -} -void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ -} -void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ -} -void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ -} -void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ -} - -void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} -void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} -void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} - -void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} - -void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ -} -void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ -} -void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ -} -void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ -} -void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ -} - -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ -} -void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ -} -void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); } -void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ -} -void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } -void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); } -void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ +} +void +host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ +} + +void +host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ +} +void +host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void +host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void +host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} + +void +host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void +host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void +host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void +host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ +} +void +host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ +} +void +host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ +} +void +host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ +} + +void +host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void +host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void +host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void +host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + +void +host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ +} +void +host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ +} +void +host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ +} +void +host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ +} +void +host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ +} +void +host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ +} + +void +host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void +host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void +host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} + +void +host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} + +void +host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void +host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void +host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void +host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ +} +void +host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ +} +void +host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ +} +void +host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ +} + +void +host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void +host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void +host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void +host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ +} +void +host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ +} +void +host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ +} + +void +host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ +} +void +host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ +} + +void +host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ +} +void +host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } #endif diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index 9997ea738..e9c08cbc8 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -1,3165 +1,3280 @@ #if defined __amd64__ || defined _M_X64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "x86.h" -#include "x87.h" -#include "386_common.h" -#include "codegen.h" -#include "codegen_backend.h" -#include "codegen_backend_x86-64_defs.h" -#include "codegen_backend_x86-64_ops.h" -#include "codegen_backend_x86-64_ops_sse.h" -#include "codegen_ir_defs.h" +# include "x86.h" +# include "x87.h" +# include "386_common.h" +# include "codegen.h" +# include "codegen_backend.h" +# include "codegen_backend_x86-64_defs.h" +# include "codegen_backend_x86-64_ops.h" +# include "codegen_backend_x86-64_ops_sse.h" +# include "codegen_ir_defs.h" -#define STACK_ARG0 (0) -#define STACK_ARG1 (4) -#define STACK_ARG2 (8) -#define STACK_ARG3 (12) +# define STACK_ARG0 (0) +# define STACK_ARG1 (4) +# define STACK_ARG2 (8) +# define STACK_ARG3 (12) -#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7)) +# define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) &3) | 4) : (IREG_GET_REG(reg) & 7)) -#define REG_IS_L(size) (size == IREG_SIZE_L) -#define REG_IS_W(size) (size == IREG_SIZE_W) -#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) -#define REG_IS_BH(size) (size == IREG_SIZE_BH) -#define REG_IS_D(size) (size == IREG_SIZE_D) -#define REG_IS_Q(size) (size == IREG_SIZE_Q) +# define REG_IS_L(size) (size == IREG_SIZE_L) +# define REG_IS_W(size) (size == IREG_SIZE_W) +# define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) +# define REG_IS_BH(size) (size == IREG_SIZE_BH) +# define REG_IS_D(size) (size == IREG_SIZE_D) +# define REG_IS_Q(size) (size == IREG_SIZE_Q) -static int codegen_ADD(codeblock_t *block, uop_t *uop) +static int +codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); - else - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (dest_reg != src_reg) - host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); - else - host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); else - fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { - if (!uop->imm_data) - { - if (uop->dest_reg_a_real == uop->src_reg_a_real) - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); - else - host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - } - else if (uop->imm_data < 4) - host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); -#ifdef RECOMPILER_DEBUG + if (!uop->imm_data) { + if (uop->dest_reg_a_real == uop->src_reg_a_real) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); else - fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); -#endif - return 0; + host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + } else if (uop->imm_data < 4) + host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); +# endif + return 0; } -static int codegen_AND(codeblock_t *block, uop_t *uop) +static int +codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_ANDN(codeblock_t *block, uop_t *uop) +static int +codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */ src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); + host_x86_CALL(block, uop->p); - return 0; + return 0; } -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); -#endif - host_x86_CALL(block, uop->p); - host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); +# endif + host_x86_CALL(block, uop->p); + host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); - return 0; + return 0; } -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_CALL(block, uop->p); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); -#endif - host_x86_JZ(block, uop->p); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); +# endif + host_x86_JZ(block, uop->p); - return 0; + return 0; } -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNZ_long(block); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JZ_long(block); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); -#endif - jump_p = host_x86_JB_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); +# endif + jump_p = host_x86_JB_long(block); + *jump_p = (uintptr_t) uop->p - ((uintptr_t) jump_p + 4); - return 0; + return 0; } -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); -#endif - jump_p = host_x86_JNBE_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); +# endif + jump_p = host_x86_JNBE_long(block); + *jump_p = (uintptr_t) uop->p - ((uintptr_t) jump_p + 4); - return 0; + return 0; } -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNB_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNB_long(block); - return 0; + return 0; } -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNBE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNBE_long(block); - return 0; + return 0; } -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNL_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNL_long(block); - return 0; + return 0; } -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNLE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNLE_long(block); - return 0; + return 0; } -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNO_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNO_long(block); - return 0; + return 0; } -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNZ_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JB_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JB_long(block); - return 0; + return 0; } -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JBE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JBE_long(block); - return 0; + return 0; } -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JL_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JL_long(block); - return 0; + return 0; } -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JLE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JLE_long(block); - return 0; + return 0; } -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JO_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JO_long(block); - return 0; + return 0; } -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JZ_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } -static int codegen_FABS(codeblock_t *block, uop_t *uop) +static int +codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) - { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); - host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); + host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_FCHS(codeblock_t *block, uop_t *uop) +static int +codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); - host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); + host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +static int +codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_FTST(codeblock_t *block, uop_t *uop) +static int +codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); - if (dest_reg != REG_EAX) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FADD(codeblock_t *block, uop_t *uop) +static int +codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FCOM(codeblock_t *block, uop_t *uop) +static int +codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); - if (dest_reg != REG_EAX) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FDIV(codeblock_t *block, uop_t *uop) +static int +codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_offset; - - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); -#if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, 7); -#else - host_x86_MOV32_REG_IMM(block, REG_EDI, 7); -#endif - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - - return 0; -} -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_offset; - - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); -#if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, 7); -#else - host_x86_MOV32_REG_IMM(block, REG_EDI, 7); -#endif - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); - host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); - - return 0; -} - -static int codegen_JMP(codeblock_t *block, uop_t *uop) -{ - host_x86_JMP(block, uop->p); - - return 0; -} - -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(src_size)) - { -#if _WIN64 - host_x86_MOVZX_REG_32_16(block, REG_ECX, src_reg); -#else - host_x86_MOVZX_REG_32_16(block, REG_EDI, src_reg); -#endif - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) -{ -#if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); -#else - host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) -{ -#if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); -#else - host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG2_IMM\n"); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG3_IMM\n"); -#endif - return 0; -} - -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); -#endif -#if _WIN64 - host_x86_MOV16_REG_REG(block, REG_CX, src_reg); - host_x86_MOV64_REG_IMM(block, REG_EDX, (uint64_t)uop->p); -#else - host_x86_MOV16_REG_REG(block, REG_DI, src_reg); - host_x86_MOV64_REG_IMM(block, REG_ESI, (uint64_t)uop->p); -#endif - host_x86_CALL(block, (void *)loadseg); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_long); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } - - return 0; -} -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_quad); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_Q(dest_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } - - return 0; -} -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *branch_offset; - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); +# if _WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, 7); +# else + host_x86_MOV32_REG_IMM(block, REG_EDI, 7); +# endif + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; - return 0; + return 0; +} +static int +codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_offset; + + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); +# if _WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, 7); +# else + host_x86_MOV32_REG_IMM(block, REG_EDI, 7); +# endif + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); + host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); + + return 0; } -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +static int +codegen_JMP(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + host_x86_JMP(block, uop->p); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + return 0; +} + +static int +codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) { +# if _WIN64 + host_x86_MOVZX_REG_32_16(block, REG_ECX, src_reg); +# else + host_x86_MOVZX_REG_32_16(block, REG_EDI, src_reg); +# endif + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +{ +# if _WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); +# else + host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +{ +# if _WIN64 + host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); +# else + host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG2_IMM\n"); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG3_IMM\n"); +# endif + return 0; +} + +static int +codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); +# endif +# if _WIN64 + host_x86_MOV16_REG_REG(block, REG_CX, src_reg); + host_x86_MOV64_REG_IMM(block, REG_EDX, (uint64_t) uop->p); +# else + host_x86_MOV16_REG_REG(block, REG_DI, src_reg); + host_x86_MOV64_REG_IMM(block, REG_ESI, (uint64_t) uop->p); +# endif + host_x86_CALL(block, (void *) loadseg); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } + + return 0; +} +static int +codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_x86_CALL(block, codegen_mem_load_quad); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_Q(dest_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } + + return 0; +} +static int +codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + + return 0; +} +static int +codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + + return 0; +} + +static int +codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_byte); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_word); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_long); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_quad); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_byte); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; +} +static int +codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_word); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_long); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; } -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MOV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); - return 0; -} -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); - } - else if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVQ_REG_XREG(block, REG_RCX, src_reg); - host_x86_CVTSI2SD_XREG_REG64(block, dest_reg, REG_RCX); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); - host_x86_TEST8_REG(block, tag_reg, tag_reg); - branch_offset = host_x86_JS_long(block); - - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG64_XREG(block, REG_RCX, src_reg); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - host_x86_MOVQ_XREG_REG(block, dest_reg, REG_RCX); - - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_NOP(codeblock_t *block, uop_t *uop) -{ - return 0; -} - -static int codegen_OR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PADDB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); - host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use RCPSS + iteration)*/ - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use RSQRTSS + iteration)*/ - host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_SAR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - if (((uintptr_t)uop->p) >> 32) - fatal("STORE_PTR_IMM 64-bit addr\n"); -#endif - host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - if (((uintptr_t)uop->p) >> 32) - fatal("STORE_PTR_IMM_8 64-bit addr\n"); -#endif - host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} - -static int codegen_SUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_x86_TEST32_REG(block, src_reg, src_reg); - } - else if (REG_IS_W(src_size)) - { - host_x86_TEST16_REG(block, src_reg, src_reg); - } - else if (REG_IS_B(src_size)) - { - host_x86_TEST8_REG(block, src_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNS_long(block); - - return 0; -} -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_x86_TEST32_REG(block, src_reg, src_reg); - } - else if (REG_IS_W(src_size)) - { - host_x86_TEST16_REG(block, src_reg, src_reg); - } - else if (REG_IS_B(src_size)) - { - host_x86_TEST8_REG(block, src_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JS_long(block); - - return 0; -} - -static int codegen_XOR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, - - [UOP_JMP & UOP_MASK] = codegen_JMP, - - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, - - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, - - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, - - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, - - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, - - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, - - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, - - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, - - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, - - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, - - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, - - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, - - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, - - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, - - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, - - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, - - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, - - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, - - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, - - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, - - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, - - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, - - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, - - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, - - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP + host_x86_CALL(block, codegen_mem_store_quad); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MOV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t) uop->p); + return 0; +} +static int +codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVSX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVQ_REG_XREG(block, REG_RCX, src_reg); + host_x86_CVTSI2SD_XREG_REG64(block, dest_reg, REG_RCX); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); + host_x86_TEST8_REG(block, tag_reg, tag_reg); + branch_offset = host_x86_JS_long(block); + + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG64_XREG(block, REG_RCX, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + host_x86_MOVQ_XREG_REG(block, dest_reg, REG_RCX); + + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + +static int +codegen_OR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); + host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RCPSS + iteration)*/ + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RSQRTSS + iteration)*/ + host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} + +static int +codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_PSUBB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_ROL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_SAR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + if (((uintptr_t) uop->p) >> 32) + fatal("STORE_PTR_IMM 64-bit addr\n"); +# endif + host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} +static int +codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + if (((uintptr_t) uop->p) >> 32) + fatal("STORE_PTR_IMM_8 64-bit addr\n"); +# endif + host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} + +static int +codegen_SUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNS_long(block); + + return 0; +} +static int +codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JS_long(block); + + return 0; +} + +static int +codegen_XOR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & + UOP_MASK] + = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & + UOP_MASK] + = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_JMP & + UOP_MASK] + = codegen_JMP, + + [UOP_LOAD_SEG & + UOP_MASK] + = codegen_LOAD_SEG, + + [UOP_LOAD_FUNC_ARG_0 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3, + + [UOP_LOAD_FUNC_ARG_0_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & + UOP_MASK] + = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & + UOP_MASK] + = codegen_STORE_PTR_IMM_8, + + [UOP_MEM_LOAD_ABS & + UOP_MASK] + = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & + UOP_MASK] + = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & + UOP_MASK] + = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & + UOP_MASK] + = codegen_MEM_LOAD_DOUBLE, + + [UOP_MEM_STORE_ABS & + UOP_MASK] + = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & + UOP_MASK] + = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & + UOP_MASK] + = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & + UOP_MASK] + = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & + UOP_MASK] + = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & + UOP_MASK] + = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & + UOP_MASK] + = codegen_MEM_STORE_DOUBLE, + + [UOP_MOV & + UOP_MASK] + = codegen_MOV, + [UOP_MOV_PTR & + UOP_MASK] + = codegen_MOV_PTR, + [UOP_MOV_IMM & + UOP_MASK] + = codegen_MOV_IMM, + [UOP_MOVSX & + UOP_MASK] + = codegen_MOVSX, + [UOP_MOVZX & + UOP_MASK] + = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & + UOP_MASK] + = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & + UOP_MASK] + = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & + UOP_MASK] + = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & + UOP_MASK] + = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_16, + + [UOP_ADD & + UOP_MASK] + = codegen_ADD, + [UOP_ADD_IMM & + UOP_MASK] + = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & + UOP_MASK] + = codegen_ADD_LSHIFT, + [UOP_AND & + UOP_MASK] + = codegen_AND, + [UOP_ANDN & + UOP_MASK] + = codegen_ANDN, + [UOP_AND_IMM & + UOP_MASK] + = codegen_AND_IMM, + [UOP_OR & + UOP_MASK] + = codegen_OR, + [UOP_OR_IMM & + UOP_MASK] + = codegen_OR_IMM, + [UOP_SUB & + UOP_MASK] + = codegen_SUB, + [UOP_SUB_IMM & + UOP_MASK] + = codegen_SUB_IMM, + [UOP_XOR & + UOP_MASK] + = codegen_XOR, + [UOP_XOR_IMM & + UOP_MASK] + = codegen_XOR_IMM, + + [UOP_SAR & + UOP_MASK] + = codegen_SAR, + [UOP_SAR_IMM & + UOP_MASK] + = codegen_SAR_IMM, + [UOP_SHL & + UOP_MASK] + = codegen_SHL, + [UOP_SHL_IMM & + UOP_MASK] + = codegen_SHL_IMM, + [UOP_SHR & + UOP_MASK] + = codegen_SHR, + [UOP_SHR_IMM & + UOP_MASK] + = codegen_SHR_IMM, + [UOP_ROL & + UOP_MASK] + = codegen_ROL, + [UOP_ROL_IMM & + UOP_MASK] + = codegen_ROL_IMM, + [UOP_ROR & + UOP_MASK] + = codegen_ROR, + [UOP_ROR_IMM & + UOP_MASK] + = codegen_ROR_IMM, + + [UOP_CMP_IMM_JZ & + UOP_MASK] + = codegen_CMP_IMM_JZ, + + [UOP_CMP_JB & + UOP_MASK] + = codegen_CMP_JB, + [UOP_CMP_JNBE & + UOP_MASK] + = codegen_CMP_JNBE, + + [UOP_CMP_JNB_DEST & + UOP_MASK] + = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & + UOP_MASK] + = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & + UOP_MASK] + = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & + UOP_MASK] + = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & + UOP_MASK] + = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & + UOP_MASK] + = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & + UOP_MASK] + = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & + UOP_MASK] + = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & + UOP_MASK] + = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & + UOP_MASK] + = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & + UOP_MASK] + = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & + UOP_MASK] + = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & + UOP_MASK] + = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & + UOP_MASK] + = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & + UOP_MASK] + = codegen_FP_ENTER, + [UOP_MMX_ENTER & + UOP_MASK] + = codegen_MMX_ENTER, + + [UOP_FADD & + UOP_MASK] + = codegen_FADD, + [UOP_FCOM & + UOP_MASK] + = codegen_FCOM, + [UOP_FDIV & + UOP_MASK] + = codegen_FDIV, + [UOP_FMUL & + UOP_MASK] + = codegen_FMUL, + [UOP_FSUB & + UOP_MASK] + = codegen_FSUB, + + [UOP_FABS & + UOP_MASK] + = codegen_FABS, + [UOP_FCHS & + UOP_MASK] + = codegen_FCHS, + [UOP_FSQRT & + UOP_MASK] + = codegen_FSQRT, + [UOP_FTST & + UOP_MASK] + = codegen_FTST, + + [UOP_PACKSSWB & + UOP_MASK] + = codegen_PACKSSWB, + [UOP_PACKSSDW & + UOP_MASK] + = codegen_PACKSSDW, + [UOP_PACKUSWB & + UOP_MASK] + = codegen_PACKUSWB, + + [UOP_PADDB & + UOP_MASK] + = codegen_PADDB, + [UOP_PADDW & + UOP_MASK] + = codegen_PADDW, + [UOP_PADDD & + UOP_MASK] + = codegen_PADDD, + [UOP_PADDSB & + UOP_MASK] + = codegen_PADDSB, + [UOP_PADDSW & + UOP_MASK] + = codegen_PADDSW, + [UOP_PADDUSB & + UOP_MASK] + = codegen_PADDUSB, + [UOP_PADDUSW & + UOP_MASK] + = codegen_PADDUSW, + + [UOP_PCMPEQB & + UOP_MASK] + = codegen_PCMPEQB, + [UOP_PCMPEQW & + UOP_MASK] + = codegen_PCMPEQW, + [UOP_PCMPEQD & + UOP_MASK] + = codegen_PCMPEQD, + [UOP_PCMPGTB & + UOP_MASK] + = codegen_PCMPGTB, + [UOP_PCMPGTW & + UOP_MASK] + = codegen_PCMPGTW, + [UOP_PCMPGTD & + UOP_MASK] + = codegen_PCMPGTD, + + [UOP_PF2ID & + UOP_MASK] + = codegen_PF2ID, + [UOP_PFADD & + UOP_MASK] + = codegen_PFADD, + [UOP_PFCMPEQ & + UOP_MASK] + = codegen_PFCMPEQ, + [UOP_PFCMPGE & + UOP_MASK] + = codegen_PFCMPGE, + [UOP_PFCMPGT & + UOP_MASK] + = codegen_PFCMPGT, + [UOP_PFMAX & + UOP_MASK] + = codegen_PFMAX, + [UOP_PFMIN & + UOP_MASK] + = codegen_PFMIN, + [UOP_PFMUL & + UOP_MASK] + = codegen_PFMUL, + [UOP_PFRCP & + UOP_MASK] + = codegen_PFRCP, + [UOP_PFRSQRT & + UOP_MASK] + = codegen_PFRSQRT, + [UOP_PFSUB & + UOP_MASK] + = codegen_PFSUB, + [UOP_PI2FD & + UOP_MASK] + = codegen_PI2FD, + + [UOP_PMADDWD & + UOP_MASK] + = codegen_PMADDWD, + [UOP_PMULHW & + UOP_MASK] + = codegen_PMULHW, + [UOP_PMULLW & + UOP_MASK] + = codegen_PMULLW, + + [UOP_PSLLW_IMM & + UOP_MASK] + = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & + UOP_MASK] + = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & + UOP_MASK] + = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & + UOP_MASK] + = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & + UOP_MASK] + = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & + UOP_MASK] + = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & + UOP_MASK] + = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & + UOP_MASK] + = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & + UOP_MASK] + = codegen_PSRLQ_IMM, + + [UOP_PSUBB & + UOP_MASK] + = codegen_PSUBB, + [UOP_PSUBW & + UOP_MASK] + = codegen_PSUBW, + [UOP_PSUBD & + UOP_MASK] + = codegen_PSUBD, + [UOP_PSUBSB & + UOP_MASK] + = codegen_PSUBSB, + [UOP_PSUBSW & + UOP_MASK] + = codegen_PSUBSW, + [UOP_PSUBUSB & + UOP_MASK] + = codegen_PSUBUSB, + [UOP_PSUBUSW & + UOP_MASK] + = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & + UOP_MASK] + = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & + UOP_MASK] + = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & + UOP_MASK] + = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & + UOP_MASK] + = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & + UOP_MASK] + = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & + UOP_MASK] + = codegen_PUNPCKLDQ, + + [UOP_NOP_BARRIER & + UOP_MASK] + = codegen_NOP }; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV8_REG_ABS(block, host_reg, p); + host_x86_MOV8_REG_ABS(block, host_reg, p); } -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV16_REG_ABS(block, host_reg, p); + host_x86_MOV16_REG_ABS(block, host_reg, p); } -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV32_REG_ABS(block, host_reg, p); + host_x86_MOV32_REG_ABS(block, host_reg, p); } -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV64_REG_ABS(block, host_reg, p); + host_x86_MOV64_REG_ABS(block, host_reg, p); } -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 0); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 0); } -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); } -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV8_ABS_REG(block, p, host_reg); + host_x86_MOV8_ABS_REG(block, p, host_reg); } -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV16_ABS_REG(block, p, host_reg); + host_x86_MOV16_ABS_REG(block, p, host_reg); } -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV32_ABS_REG(block, p, host_reg); + host_x86_MOV32_ABS_REG(block, p, host_reg); } -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } -void codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV64_ABS_REG(block, p, host_reg); + host_x86_MOV64_ABS_REG(block, p, host_reg); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); } -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV64_ABS_REG(block, p, host_reg); + host_x86_MOV64_ABS_REG(block, p, host_reg); } -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV64_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOV64_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); } -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); } -void codegen_direct_write_pointer_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_pointer_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOV64_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOV64_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); } -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); } -void codegen_set_jump_dest(codeblock_t *block, void *p) +void +codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); + *(uint32_t *) p = (uintptr_t) &block_write_data[block_pos] - ((uintptr_t) p + 4); } -void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) +void +codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) { - host_x86_MOV8_ABS_IMM(block, p, imm_data); + host_x86_MOV8_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) +void +codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) { - host_x86_MOV16_ABS_IMM(block, p, imm_data); + host_x86_MOV16_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) +void +codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) { - host_x86_MOV32_ABS_IMM(block, p, imm_data); + host_x86_MOV32_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) +void +codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) { - host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); + host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); } #endif diff --git a/src/codegen_new/codegen_backend_x86.c b/src/codegen_new/codegen_backend_x86.c index 14327607b..2de794ad1 100644 --- a/src/codegen_new/codegen_backend_x86.c +++ b/src/codegen_new/codegen_backend_x86.c @@ -1,29 +1,29 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops.h" -#include "codegen_backend_x86_ops_sse.h" -#include "codegen_reg.h" -#include "x86.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops.h" +# include "codegen_backend_x86_ops_sse.h" +# include "codegen_reg.h" +# include "x86.h" -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#include -#endif -#include +# if defined(__linux__) || defined(__APPLE__) +# include +# include +# endif +# if defined WIN32 || defined _WIN32 || defined _WIN32 +# include +# endif +# include void *codegen_mem_load_byte; void *codegen_mem_load_word; @@ -42,306 +42,303 @@ void *codegen_mem_store_double; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - /*Note: while EAX and EDX are normally volatile registers under x86 - calling conventions, the recompiler will explicitly save and restore - them across funcion calls*/ - {REG_EAX, 0}, - {REG_EBX, 0}, - {REG_EDX, 0} +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + /*Note: while EAX and EDX are normally volatile registers under x86 + calling conventions, the recompiler will explicitly save and restore + them across funcion calls*/ + {REG_EAX, 0}, + { REG_EBX, 0}, + { REG_EDX, 0} }; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ - {REG_XMM0, HOST_REG_FLAG_VOLATILE}, - {REG_XMM1, HOST_REG_FLAG_VOLATILE}, - {REG_XMM2, HOST_REG_FLAG_VOLATILE}, - {REG_XMM3, HOST_REG_FLAG_VOLATILE}, - {REG_XMM4, HOST_REG_FLAG_VOLATILE}, - {REG_XMM5, HOST_REG_FLAG_VOLATILE} +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { + {REG_XMM0, HOST_REG_FLAG_VOLATILE}, + { REG_XMM1, HOST_REG_FLAG_VOLATILE}, + { REG_XMM2, HOST_REG_FLAG_VOLATILE}, + { REG_XMM3, HOST_REG_FLAG_VOLATILE}, + { REG_XMM4, HOST_REG_FLAG_VOLATILE}, + { REG_XMM5, HOST_REG_FLAG_VOLATILE} }; -static void build_load_routine(codeblock_t *block, int size, int is_float) +static void +build_load_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset = NULL; + uint8_t *branch_offset; + uint8_t *misaligned_offset = NULL; - /*In - ESI = address - Out - ECX = data, ESI = abrt*/ - /*MOV ECX, ESI - SHR ESI, 12 - MOV ESI, [readlookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOVZX ECX, B[ESI+ECX] - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL readmembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, readlookup2, REG_ESI, 2); - if (size != 1) - { - host_x86_TEST32_REG_IMM(block, REG_ECX, size-1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 2 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 4 && !is_float) - host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 4 && is_float) - host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); - else if (size == 8) - host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); - else - fatal("build_load_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ESI = address + Out - ECX = data, ESI = abrt*/ + /*MOV ECX, ESI + SHR ESI, 12 + MOV ESI, [readlookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOVZX ECX, B[ESI+ECX] + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL readmembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, readlookup2, REG_ESI, 2); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_ECX, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t) -1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 2 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 4 && !is_float) + host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 4 && is_float) + host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); + else if (size == 8) + host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); + else + fatal("build_load_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - host_x86_PUSH(block, REG_EAX); - host_x86_PUSH(block, REG_EDX); - host_x86_PUSH(block, REG_ECX); - if (size == 1) - host_x86_CALL(block, (void *)readmembl); - else if (size == 2) - host_x86_CALL(block, (void *)readmemwl); - else if (size == 4) - host_x86_CALL(block, (void *)readmemll); - else if (size == 8) - host_x86_CALL(block, (void *)readmemql); - host_x86_POP(block, REG_ECX); - if (size == 1 && !is_float) - host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); - else if (size == 2 && !is_float) - host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); - else if (size == 4 && !is_float) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - else if (size == 4 && is_float) - { - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); - host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - } - else if (size == 8) - { - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX); - host_x86_UNPCKLPS_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP2); - } - host_x86_POP(block, REG_EDX); - host_x86_POP(block, REG_EAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); - block_pos = (block_pos + 63) & ~63; + *branch_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 1; + host_x86_PUSH(block, REG_EAX); + host_x86_PUSH(block, REG_EDX); + host_x86_PUSH(block, REG_ECX); + if (size == 1) + host_x86_CALL(block, (void *) readmembl); + else if (size == 2) + host_x86_CALL(block, (void *) readmemwl); + else if (size == 4) + host_x86_CALL(block, (void *) readmemll); + else if (size == 8) + host_x86_CALL(block, (void *) readmemql); + host_x86_POP(block, REG_ECX); + if (size == 1 && !is_float) + host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); + else if (size == 2 && !is_float) + host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); + else if (size == 4 && !is_float) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + else if (size == 4 && is_float) { + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + } else if (size == 8) { + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX); + host_x86_UNPCKLPS_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP2); + } + host_x86_POP(block, REG_EDX); + host_x86_POP(block, REG_EAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; } -static void build_store_routine(codeblock_t *block, int size, int is_float) +static void +build_store_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset = NULL; + uint8_t *branch_offset; + uint8_t *misaligned_offset = NULL; - /*In - ECX = data, ESI = address - Out - ESI = abrt - Corrupts EDI*/ - /*MOV EDI, ESI - SHR ESI, 12 - MOV ESI, [writelookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOV [ESI+EDI], ECX - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL writemembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, writelookup2, REG_ESI, 2); - if (size != 1) - { - host_x86_TEST32_REG_IMM(block, REG_EDI, size-1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOV8_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 2 && !is_float) - host_x86_MOV16_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 4 && !is_float) - host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 4 && is_float) - host_x86_MOVD_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); - else if (size == 8) - host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); - else - fatal("build_store_routine: size=%i is_float=%i\n", size, is_float); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ECX = data, ESI = address + Out - ESI = abrt + Corrupts EDI*/ + /*MOV EDI, ESI + SHR ESI, 12 + MOV ESI, [writelookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOV [ESI+EDI], ECX + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL writemembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, writelookup2, REG_ESI, 2); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_EDI, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t) -1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOV8_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 2 && !is_float) + host_x86_MOV16_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 4 && !is_float) + host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 4 && is_float) + host_x86_MOVD_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); + else if (size == 8) + host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); + else + fatal("build_store_routine: size=%i is_float=%i\n", size, is_float); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - if (size == 4 && is_float) - host_x86_MOVD_REG_XREG(block, REG_ECX, REG_XMM_TEMP); - host_x86_PUSH(block, REG_EAX); - host_x86_PUSH(block, REG_EDX); - host_x86_PUSH(block, REG_ECX); - if (size == 8) - { - host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP); - host_x86_SUB32_REG_IMM(block, REG_ESP, 8); - } - host_x86_PUSH(block, REG_EDI); - if (size == 1) - host_x86_CALL(block, (void *)writemembl); - else if (size == 2) - host_x86_CALL(block, (void *)writememwl); - else if (size == 4) - host_x86_CALL(block, (void *)writememll); - else if (size == 8) - host_x86_CALL(block, (void *)writememql); - host_x86_POP(block, REG_EDI); - if (size == 8) - host_x86_ADD32_REG_IMM(block, REG_ESP, 8); - host_x86_POP(block, REG_ECX); - host_x86_POP(block, REG_EDX); - host_x86_POP(block, REG_EAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); - block_pos = (block_pos + 63) & ~63; + *branch_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 1; + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_ECX, REG_XMM_TEMP); + host_x86_PUSH(block, REG_EAX); + host_x86_PUSH(block, REG_EDX); + host_x86_PUSH(block, REG_ECX); + if (size == 8) { + host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP); + host_x86_SUB32_REG_IMM(block, REG_ESP, 8); + } + host_x86_PUSH(block, REG_EDI); + if (size == 1) + host_x86_CALL(block, (void *) writemembl); + else if (size == 2) + host_x86_CALL(block, (void *) writememwl); + else if (size == 4) + host_x86_CALL(block, (void *) writememll); + else if (size == 8) + host_x86_CALL(block, (void *) writememql); + host_x86_POP(block, REG_EDI); + if (size == 8) + host_x86_ADD32_REG_IMM(block, REG_ESP, 8); + host_x86_POP(block, REG_ECX); + host_x86_POP(block, REG_EDX); + host_x86_POP(block, REG_EAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; } -static void build_loadstore_routines(codeblock_t *block) +static void +build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } -void codegen_backend_init() +void +codegen_backend_init(void) { - codeblock_t *block; - int c; + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block_write_data = block->data; - build_loadstore_routines(block); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(block); - codegen_gpf_rout = &codeblock[block_current].data[block_pos]; - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0); - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); - host_x86_CALL(block, (void *)x86gpf); - codegen_exit_rout = &codeblock[block_current].data[block_pos]; - host_x86_ADD32_REG_IMM(block, REG_ESP, 64); - host_x86_POP(block, REG_EDI); - host_x86_POP(block, REG_ESI); - host_x86_POP(block, REG_EBP); - host_x86_POP(block, REG_EDX); - host_x86_RET(block); - block_write_data = NULL; + codegen_gpf_rout = &codeblock[block_current].data[block_pos]; + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0); + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); + host_x86_CALL(block, (void *) x86gpf); + codegen_exit_rout = &codeblock[block_current].data[block_pos]; + host_x86_ADD32_REG_IMM(block, REG_ESP, 64); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ESI); + host_x86_POP(block, REG_EBP); + host_x86_POP(block, REG_EDX); + host_x86_RET(block); + block_write_data = NULL; - cpu_state.old_fp_control = 0; - asm( - "fstcw %0\n" - "stmxcsr %1\n" - : "=m" (cpu_state.old_fp_control2), - "=m" (cpu_state.old_fp_control) - ); - cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; + cpu_state.old_fp_control = 0; + asm( + "fstcw %0\n" + "stmxcsr %1\n" + : "=m"(cpu_state.old_fp_control2), + "=m"(cpu_state.old_fp_control)); + cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; } -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - /*SSE*/ - cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); - /*x87 - used for double -> i64 conversions*/ - cpu_state.new_fp_control2 = (cpu_state.old_fp_control2 & ~0x0c00) | (mode << 10); + /*SSE*/ + cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); + /*x87 - used for double -> i64 conversions*/ + cpu_state.new_fp_control2 = (cpu_state.old_fp_control2 & ~0x0c00) | (mode << 10); } -void codegen_backend_prologue(codeblock_t *block) +void +codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; /*Entry code*/ - host_x86_PUSH(block, REG_EBX); - host_x86_PUSH(block, REG_EBP); - host_x86_PUSH(block, REG_ESI); - host_x86_PUSH(block, REG_EDI); - host_x86_SUB32_REG_IMM(block, REG_ESP, 64); - host_x86_MOV32_REG_IMM(block, REG_EBP, ((uintptr_t)&cpu_state) + 128); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); - host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); - host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); - } + block_pos = BLOCK_START; /*Entry code*/ + host_x86_PUSH(block, REG_EBX); + host_x86_PUSH(block, REG_EBP); + host_x86_PUSH(block, REG_ESI); + host_x86_PUSH(block, REG_EDI); + host_x86_SUB32_REG_IMM(block, REG_ESP, 64); + host_x86_MOV32_REG_IMM(block, REG_EBP, ((uintptr_t) &cpu_state) + 128); + if (block->flags & CODEBLOCK_HAS_FPU) { + host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); + host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); + } } -void codegen_backend_epilogue(codeblock_t *block) +void +codegen_backend_epilogue(codeblock_t *block) { - host_x86_ADD32_REG_IMM(block, REG_ESP, 64); - host_x86_POP(block, REG_EDI); - host_x86_POP(block, REG_ESI); - host_x86_POP(block, REG_EBP); - host_x86_POP(block, REG_EDX); - host_x86_RET(block); + host_x86_ADD32_REG_IMM(block, REG_ESP, 64); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ESI); + host_x86_POP(block, REG_EBP); + host_x86_POP(block, REG_EDX); + host_x86_RET(block); } #endif diff --git a/src/codegen_new/codegen_backend_x86.h b/src/codegen_new/codegen_backend_x86.h index 582e46430..646289fab 100644 --- a/src/codegen_new/codegen_backend_x86.h +++ b/src/codegen_new/codegen_backend_x86.h @@ -1,14 +1,14 @@ #include "codegen_backend_x86_defs.h" -#define BLOCK_SIZE 0x10000 -#define BLOCK_MASK 0xffff +#define BLOCK_SIZE 0x10000 +#define BLOCK_MASK 0xffff #define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) -#define BLOCK_MAX 0x3c0 +#define BLOCK_MAX 0x3c0 #define CODEGEN_BACKEND_HAS_MOV_IMM diff --git a/src/codegen_new/codegen_backend_x86_defs.h b/src/codegen_new/codegen_backend_x86_defs.h index 25964ba3c..a86d6f309 100644 --- a/src/codegen_new/codegen_backend_x86_defs.h +++ b/src/codegen_new/codegen_backend_x86_defs.h @@ -1,28 +1,28 @@ #ifndef _CODEGEN_BACKEND_X86_DEFS_H_ #define _CODEGEN_BACKEND_X86_DEFS_H_ -#define REG_EAX 0 -#define REG_ECX 1 -#define REG_EDX 2 -#define REG_EBX 3 -#define REG_ESP 4 -#define REG_EBP 5 -#define REG_ESI 6 -#define REG_EDI 7 +#define REG_EAX 0 +#define REG_ECX 1 +#define REG_EDX 2 +#define REG_EBX 3 +#define REG_ESP 4 +#define REG_EBP 5 +#define REG_ESI 6 +#define REG_EDI 7 -#define REG_XMM0 0 -#define REG_XMM1 1 -#define REG_XMM2 2 -#define REG_XMM3 3 -#define REG_XMM4 4 -#define REG_XMM5 5 -#define REG_XMM6 6 -#define REG_XMM7 7 +#define REG_XMM0 0 +#define REG_XMM1 1 +#define REG_XMM2 2 +#define REG_XMM3 3 +#define REG_XMM4 4 +#define REG_XMM5 5 +#define REG_XMM6 6 +#define REG_XMM7 7 -#define REG_XMM_TEMP REG_XMM7 -#define REG_XMM_TEMP2 REG_XMM6 +#define REG_XMM_TEMP REG_XMM7 +#define REG_XMM_TEMP2 REG_XMM6 -#define CODEGEN_HOST_REGS 3 +#define CODEGEN_HOST_REGS 3 #define CODEGEN_HOST_FP_REGS 6 extern void *codegen_mem_load_byte; diff --git a/src/codegen_new/codegen_backend_x86_ops.c b/src/codegen_new/codegen_backend_x86_ops.c index 5e89ffbc8..4807caacf 100644 --- a/src/codegen_new/codegen_backend_x86_ops.c +++ b/src/codegen_new/codegen_backend_x86_ops.c @@ -1,1334 +1,1311 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops.h" -#include "codegen_backend_x86_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops.h" +# include "codegen_backend_x86_ops_helpers.h" -#define RM_OP_ADD 0x00 -#define RM_OP_OR 0x08 -#define RM_OP_AND 0x20 -#define RM_OP_SUB 0x28 -#define RM_OP_XOR 0x30 -#define RM_OP_CMP 0x38 +# define RM_OP_ADD 0x00 +# define RM_OP_OR 0x08 +# define RM_OP_AND 0x20 +# define RM_OP_SUB 0x28 +# define RM_OP_XOR 0x30 +# define RM_OP_CMP 0x38 -#define RM_OP_ROL 0x00 -#define RM_OP_ROR 0x08 -#define RM_OP_SHL 0x20 -#define RM_OP_SHR 0x28 -#define RM_OP_SAR 0x38 +# define RM_OP_ROL 0x00 +# define RM_OP_ROR 0x08 +# define RM_OP_SHL 0x20 +# define RM_OP_SHR 0x28 +# define RM_OP_SAR 0x38 -void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x03, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x03); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } -} - -void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ - } -} -void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ -} -void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ + codegen_addbyte3(block, 0x03, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x03); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) + +void +host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ + } } - -void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ - } -} -void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ -} -void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ -} -void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ -} - -void host_x86_CALL(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xe8); /*CALL*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} - -void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} -void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} -void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} - -void host_x86_INC32_ABS(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xff, 0x05); /*INC p*/ - codegen_addlong(block, (uint32_t)p); -} - -void host_x86_JMP(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} -uint32_t *host_x86_JMP_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} - -void host_x86_JNZ(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} -void host_x86_JZ(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} - -uint8_t *host_x86_JNZ_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x75, 0); /*JNZ*/ - return &block_write_data[block_pos-1]; -} -uint8_t *host_x86_JS_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x78, 0); /*JS*/ - return &block_write_data[block_pos-1]; -} -uint8_t *host_x86_JZ_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x74, 0); /*JZ*/ - return &block_write_data[block_pos-1]; -} - -uint32_t *host_x86_JNB_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNBE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNL_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNLE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNO_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNS_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNZ_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JB_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JBE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JL_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JLE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JO_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JS_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JZ_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} - -void host_x86_LAHF(codeblock_t *block) -{ - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x9f); /*LAHF*/ -} - -void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) -{ - if (offset) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ - codegen_addlong(block, offset); - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ - } -} - -void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b]*/ -} -void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ -} - -void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ - codegen_addbyte(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addbyte(block, imm_data); - } -} -void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0xc7, 0x05); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addword(block, imm_data); - } -} -void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addlong(block, imm_data); - } -} - -void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x89, 0x05 | (src_reg << 3)); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } -} - -void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int idx_reg, int shift, int src_reg) -{ - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } -} - -void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV B[base_reg + idx_reg], src_reg*/ -} -void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +void +host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV W[base_reg + idx_reg], src_reg*/ + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +void +host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } -void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8a, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x8a); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x8b, 0x05 | (dst_reg << 3)); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift) +void +host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ + } +} +void +host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void +host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ +} +void +host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ +} +void +host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ +} + +void +host_x86_CALL(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xe8); /*CALL*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} + +void +host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void +host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void +host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void +host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} + +void +host_x86_INC32_ABS(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xff, 0x05); /*INC p*/ + codegen_addlong(block, (uint32_t) p); +} + +void +host_x86_JMP(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} +uint32_t * +host_x86_JMP_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} + +void +host_x86_JNZ(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} +void +host_x86_JZ(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} + +uint8_t * +host_x86_JNZ_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x75, 0); /*JNZ*/ + return &block_write_data[block_pos - 1]; +} +uint8_t * +host_x86_JS_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x78, 0); /*JS*/ + return &block_write_data[block_pos - 1]; +} +uint8_t * +host_x86_JZ_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x74, 0); /*JZ*/ + return &block_write_data[block_pos - 1]; +} + +uint32_t * +host_x86_JNB_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNBE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNL_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNLE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNO_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNS_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNZ_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JB_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JBE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JL_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JLE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JO_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JS_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JZ_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} + +void +host_x86_LAHF(codeblock_t *block) +{ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x9f); /*LAHF*/ +} + +void +host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) +{ + if (offset) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ + codegen_addlong(block, offset); + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ + } +} + +void +host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b]*/ +} +void +host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ +} + +void +host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ + codegen_addbyte(block, imm_data); + } else { codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (shift << 6) | (idx_reg << 3) | 0x05); /*MOV dst_reg, [p + idx_reg << shift]*/ - codegen_addlong(block, (uint32_t)p); + codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t) p); + codegen_addbyte(block, imm_data); + } +} +void +host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t) p); + codegen_addword(block, imm_data); + } +} +void +host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t) p); + codegen_addlong(block, imm_data); + } } -void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int idx_reg, int shift) +void +host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) { - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ + codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } } +void +host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); -} -void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); -} - -void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } - else - fatal("MOV16_BASE_OFFSET_REG - offset %i\n", offset); -} -void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } - else - fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); -} - -void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); - codegen_addlong(block, imm_data); - } - } - else - fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); -} - -void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ -} -void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (!imm_data) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (!imm_data) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); -} - -void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) -{ - if (!offset) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else if (offset >= -0x80 && offset < 0x80) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 11); - codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, offset); - codegen_addlong(block, imm_data); - } -} - -void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x89, 0x05 | (src_reg << 3)); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ -} -void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ - } - else - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xb7, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} - -void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int idx_reg, int shift, int src_reg) { + if (addr < 0x80 || addr >= 0xffffff80) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} -void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} -void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } } -void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +void +host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV B[base_reg + idx_reg], src_reg*/ +} +void +host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV W[base_reg + idx_reg], src_reg*/ +} +void +host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ +} + +void +host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8a, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x8a); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } +} +void +host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, B[base_reg + idx_reg]*/ + codegen_addbyte4(block, 0x66, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x8b, 0x05 | (dst_reg << 3)); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +void +host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } +} + +void +host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift) +{ + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (shift << 6) | (idx_reg << 3) | 0x05); /*MOV dst_reg, [p + idx_reg << shift]*/ + codegen_addlong(block, (uint32_t) p); +} + +void +host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int idx_reg, int shift) +{ + if (addr < 0x80 || addr >= 0xffffff80) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ + codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } } -void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ } -void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) + +void +host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); +} +void +host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} + +void +host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV16_BASE_OFFSET_REG - offset %i\n", offset); +} +void +host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); +} + +void +host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); + codegen_addlong(block, imm_data); + } + } else + fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); +} + +void +host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ +} +void +host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (!imm_data) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (!imm_data) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); + } } -void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); } -void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +void +host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); } -void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +void +host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); } -void host_x86_POP(codeblock_t *block, int src_reg) +void +host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ + if (!offset) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else if (offset >= -0x80 && offset < 0x80) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 11); + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } } -void host_x86_PUSH(codeblock_t *block, int src_reg) +void +host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void +host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void +host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } -void host_x86_RET(codeblock_t *block) +void +host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0xc3); /*RET*/ -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_ROL8_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } else { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_ROL16_CL(codeblock_t *block, int dst_reg) +void +host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_ROL32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_ROR8_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_ROR16_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_ROR32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} - -void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xb7, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t) p); + } } -#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) - -void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +void +host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void +host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void +host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} + +void +host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, B[base_reg + idx_reg]*/ +} +void +host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ +} + +void +host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ +} +void +host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ +} +void +host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ +} + +void +host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} -void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) -{ + codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ + } } -void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} - -void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ -} -void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } -void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) +void +host_x86_POP(codeblock_t *block, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ } -void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PUSH(codeblock_t *block, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ } -void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) + +void +host_x86_RET(codeblock_t *block) { + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0xc3); /*RET*/ +} + +void +host_x86_ROL8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_ROL16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_ROL32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} + +void +host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void +host_x86_ROR8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_ROR16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_ROR32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} + +void +host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +# define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) + +void +host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void +host_x86_SAR16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void +host_x86_SAR32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} + +void +host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void +host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void +host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} + +void +host_x86_SHL8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_SHL16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_SHL32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} + +void +host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void +host_x86_SHR8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_SHR16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_SHR32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} + +void +host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +void +host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ + } +} +void +host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} - -void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} - -void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } -void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +void +host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +void +host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void +host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ +} +void +host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ +} +void +host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ +} + +void +host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ -} -void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ + codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ + } } -void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } - -void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +void +host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ -} -void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ -} -void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ -} - -void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ - } -} -void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } #endif diff --git a/src/codegen_new/codegen_backend_x86_ops.h b/src/codegen_new/codegen_backend_x86_ops.h index 53b6e0e73..0890286ef 100644 --- a/src/codegen_new/codegen_backend_x86_ops.h +++ b/src/codegen_new/codegen_backend_x86_ops.h @@ -27,7 +27,7 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_INC32_ABS(codeblock_t *block, void *p); -void host_x86_JMP(codeblock_t *block, void *p); +void host_x86_JMP(codeblock_t *block, void *p); uint32_t *host_x86_JMP_short(codeblock_t *block); uint32_t *host_x86_JMP_long(codeblock_t *block); diff --git a/src/codegen_new/codegen_backend_x86_ops_fpu.c b/src/codegen_new/codegen_backend_x86_ops_fpu.c index cb8f36ac6..13f90743a 100644 --- a/src/codegen_new/codegen_backend_x86_ops_fpu.c +++ b/src/codegen_new/codegen_backend_x86_ops_fpu.c @@ -1,84 +1,74 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops_fpu.h" -#include "codegen_backend_x86_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops_fpu.h" +# include "codegen_backend_x86_ops_helpers.h" -void host_x87_FILDq_BASE(codeblock_t *block, int base_reg) +void +host_x87_FILDq_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ + } } -void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg) +void +host_x87_FISTPq_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ + } } -void host_x87_FLDCW(codeblock_t *block, void *p) +void +host_x87_FLDCW(codeblock_t *block, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x87_FLDd_BASE(codeblock_t *block, int base_reg) +void +host_x87_FLDd_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ + } } -void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) +void +host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ + } } #endif diff --git a/src/codegen_new/codegen_backend_x86_ops_helpers.h b/src/codegen_new/codegen_backend_x86_ops_helpers.h index 3fca4f4d2..0a6469a89 100644 --- a/src/codegen_new/codegen_backend_x86_ops_helpers.h +++ b/src/codegen_new/codegen_backend_x86_ops_helpers.h @@ -1,84 +1,94 @@ #define JMP_LEN_BYTES 5 -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +static inline void +codegen_addbyte(codeblock_t *block, uint8_t val) { - if (block_pos >= BLOCK_MAX) - fatal("codegen_addbyte over! %i\n", block_pos); - block_write_data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) + fatal("codegen_addbyte over! %i\n", block_pos); + block_write_data[block_pos++] = val; } -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +static inline void +codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) { - if (block_pos > (BLOCK_MAX-2)) - fatal("codegen_addbyte2 over! %i\n", block_pos); - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; + if (block_pos > (BLOCK_MAX - 2)) + fatal("codegen_addbyte2 over! %i\n", block_pos); + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; } -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +static inline void +codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) { - if (block_pos > (BLOCK_MAX-3)) - fatal("codegen_addbyte3 over! %i\n", block_pos); - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; + if (block_pos > (BLOCK_MAX - 3)) + fatal("codegen_addbyte3 over! %i\n", block_pos); + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; } -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +static inline void +codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { - if (block_pos > (BLOCK_MAX-4)) - fatal("codegen_addbyte4 over! %i\n", block_pos); - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; - block_write_data[block_pos++] = vald; + if (block_pos > (BLOCK_MAX - 4)) + fatal("codegen_addbyte4 over! %i\n", block_pos); + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; + block_write_data[block_pos++] = vald; } -static inline void codegen_addword(codeblock_t *block, uint16_t val) +static inline void +codegen_addword(codeblock_t *block, uint16_t val) { - if (block_pos > (BLOCK_MAX-2)) - fatal("codegen_addword over! %i\n", block_pos); - *(uint16_t *)&block_write_data[block_pos] = val; - block_pos += 2; + if (block_pos > (BLOCK_MAX - 2)) + fatal("codegen_addword over! %i\n", block_pos); + *(uint16_t *) &block_write_data[block_pos] = val; + block_pos += 2; } -static inline void codegen_addlong(codeblock_t *block, uint32_t val) +static inline void +codegen_addlong(codeblock_t *block, uint32_t val) { - if (block_pos > (BLOCK_MAX-4)) - fatal("codegen_addlong over! %i\n", block_pos); - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; + if (block_pos > (BLOCK_MAX - 4)) + fatal("codegen_addlong over! %i\n", block_pos); + *(uint32_t *) &block_write_data[block_pos] = val; + block_pos += 4; } -static inline void codegen_addquad(codeblock_t *block, uint64_t val) +static inline void +codegen_addquad(codeblock_t *block, uint64_t val) { - if (block_pos > (BLOCK_MAX-8)) - fatal("codegen_addquad over! %i\n", block_pos); - *(uint64_t *)&block_write_data[block_pos] = val; - block_pos += 8; + if (block_pos > (BLOCK_MAX - 8)) + fatal("codegen_addquad over! %i\n", block_pos); + *(uint64_t *) &block_write_data[block_pos] = val; + block_pos += 8; } -static void codegen_allocate_new_block(codeblock_t *block) +static void +codegen_allocate_new_block(codeblock_t *block) { - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - /*Add a jump instruction to the new block*/ - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); + /*Add a jump instruction to the new block*/ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t) new_ptr - (uintptr_t) &block_write_data[block_pos + 4]); - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; } -static inline void codegen_alloc_bytes(codeblock_t *block, int size) +static inline void +codegen_alloc_bytes(codeblock_t *block, int size) { - if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) - codegen_allocate_new_block(block); + if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) + codegen_allocate_new_block(block); } -static inline int is_imm8(uint32_t imm_data) +static inline int +is_imm8(uint32_t imm_data) { - if (imm_data <= 0x7f || imm_data >= 0xffffff80) - return 1; - return 0; + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; } diff --git a/src/codegen_new/codegen_backend_x86_ops_sse.c b/src/codegen_new/codegen_backend_x86_ops_sse.c index 0ab461e74..a1e04db30 100644 --- a/src/codegen_new/codegen_backend_x86_ops_sse.c +++ b/src/codegen_new/codegen_backend_x86_ops_sse.c @@ -1,578 +1,629 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops_sse.h" -#include "codegen_backend_x86_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops_sse.h" +# include "codegen_backend_x86_ops_helpers.h" -void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ } -void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +void +host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ } -void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +void +host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); } -void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ } -void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ } -void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ } -void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ } -void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } -void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } -void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +void +host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} + +void +host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ +} +void +host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ +} + +void +host_x86_LDMXCSR(codeblock_t *block, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ + codegen_addlong(block, (uint32_t) p); + } +} + +void +host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ +} + +void +host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); +} +void +host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t) p); + } } - -void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ -} -void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ -} - -void host_x86_LDMXCSR(codeblock_t *block, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} - -void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ -} - -void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) -{ - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); -} -void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg) -{ - if (!offset) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ - codegen_addbyte(block, 0x24); - } - else if (offset >= -0x80 && offset < 0x80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ - codegen_addbyte2(block, 0x24, offset & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ - codegen_addbyte(block, 0x24); - codegen_addlong(block, offset); - } - -} - -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) -{ - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); -} -void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ -} - -void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ -} -void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ -} - -void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ -} -void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) { + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } -void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); +} +void +host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg) +{ + if (!offset) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ + codegen_addbyte(block, 0x24); + } else if (offset >= -0x80 && offset < 0x80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte2(block, 0x24, offset & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte(block, 0x24); + codegen_addlong(block, offset); + } } -void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) + +void +host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) { + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t) p); + } +} +void +host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +{ + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} +void +host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); +} +void +host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } -void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ } -void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ -} -void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ -} -void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ -} -void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ } -void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ } -void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ -} -void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ -} -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } -void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } -void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ -} -void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ -} -void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ -} -void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } -void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } -void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } -void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void +host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ +} +void +host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ +} +void +host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ +} +void +host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ } -void host_x86_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle) +void +host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | src_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, shuffle); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void +host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void +host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void +host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ } -void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ } -void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ } -void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ } -void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ } -void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ } -void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ } -void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } -void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } -void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ -} -void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ -} -void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ -} -void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } -void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ -} -void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ -} -void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | src_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, shuffle); } -void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); } -void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); } -void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } -void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void +host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void +host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ +} +void +host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ +} +void +host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ +} +void +host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } -void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ +} +void +host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ +} +void +host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ +} + +void +host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ +} +void +host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ +} + +void +host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ +} +void +host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } #endif diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c index 3f7e2dd9a..83844b3cd 100644 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ b/src/codegen_new/codegen_backend_x86_uops.c @@ -1,3164 +1,3286 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "x86.h" -#include "x86_ops.h" -#include "386_common.h" -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops.h" -#include "codegen_backend_x86_ops_fpu.h" -#include "codegen_backend_x86_ops_sse.h" -#include "codegen_ir_defs.h" +# include "x86.h" +# include "x86_ops.h" +# include "386_common.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops.h" +# include "codegen_backend_x86_ops_fpu.h" +# include "codegen_backend_x86_ops_sse.h" +# include "codegen_ir_defs.h" -#define HOST_REG_IS_L(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_L) -#define HOST_REG_IS_W(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_W) -#define HOST_REG_IS_B(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_B && IREG_GET_REG(reg) < 4) -#define HOST_REG_IS_BH(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_BH && IREG_GET_REG(reg) < 4) +# define HOST_REG_IS_L(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_L) +# define HOST_REG_IS_W(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_W) +# define HOST_REG_IS_B(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_B && IREG_GET_REG(reg) < 4) +# define HOST_REG_IS_BH(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_BH && IREG_GET_REG(reg) < 4) -#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7)) +# define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) &3) | 4) : (IREG_GET_REG(reg) & 7)) -#define REG_IS_L(size) (size == IREG_SIZE_L) -#define REG_IS_W(size) (size == IREG_SIZE_W) -#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) -#define REG_IS_BH(size) (size == IREG_SIZE_BH) -#define REG_IS_D(size) (size == IREG_SIZE_D) -#define REG_IS_Q(size) (size == IREG_SIZE_Q) +# define REG_IS_L(size) (size == IREG_SIZE_L) +# define REG_IS_W(size) (size == IREG_SIZE_W) +# define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) +# define REG_IS_BH(size) (size == IREG_SIZE_BH) +# define REG_IS_D(size) (size == IREG_SIZE_D) +# define REG_IS_Q(size) (size == IREG_SIZE_Q) -static int codegen_ADD(codeblock_t *block, uop_t *uop) +static int +codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); - else - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); - else - host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); else - fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { - if (!uop->imm_data) - { - if (uop->dest_reg_a_real == uop->src_reg_a_real) - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); - else - host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - } - else if (uop->imm_data < 4) - host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); -#ifdef RECOMPILER_DEBUG + if (!uop->imm_data) { + if (uop->dest_reg_a_real == uop->src_reg_a_real) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); else - fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); -#endif - return 0; + host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + } else if (uop->imm_data < 4) + host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); +# endif + return 0; } -static int codegen_AND(codeblock_t *block, uop_t *uop) +static int +codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_ANDN(codeblock_t *block, uop_t *uop) +static int +codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */ src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); + host_x86_CALL(block, uop->p); - return 0; + return 0; } -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); -#endif - host_x86_CALL(block, uop->p); - host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); +# endif + host_x86_CALL(block, uop->p); + host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); - return 0; + return 0; } -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); -// host_x86_CALL(block, codegen_debug); + host_x86_CALL(block, uop->p); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); + // host_x86_CALL(block, codegen_debug); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); -#endif - host_x86_JZ(block, uop->p); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); +# endif + host_x86_JZ(block, uop->p); - return 0; + return 0; } -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNZ_long(block); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JZ_long(block); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); -#endif - jump_p = host_x86_JB_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); +# endif + jump_p = host_x86_JB_long(block); + *jump_p = (uintptr_t) uop->p - ((uintptr_t) jump_p + 4); - return 0; + return 0; } -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); -#endif - jump_p = host_x86_JNBE_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); +# endif + jump_p = host_x86_JNBE_long(block); + *jump_p = (uintptr_t) uop->p - ((uintptr_t) jump_p + 4); - return 0; + return 0; } -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNB_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNB_long(block); - return 0; + return 0; } -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNBE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNBE_long(block); - return 0; + return 0; } -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNL_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNL_long(block); - return 0; + return 0; } -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNLE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNLE_long(block); - return 0; + return 0; } -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNO_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNO_long(block); - return 0; + return 0; } -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNZ_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JB_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JB_long(block); - return 0; + return 0; } -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JBE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JBE_long(block); - return 0; + return 0; } -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JL_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JL_long(block); - return 0; + return 0; } -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JLE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JLE_long(block); - return 0; + return 0; } -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JO_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JO_long(block); - return 0; + return 0; } -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JZ_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } -static int codegen_FABS(codeblock_t *block, uop_t *uop) +static int +codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) - { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); - host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); + host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_FCHS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); + host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_FSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_FTST(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FCHS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); - host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); +static int +codegen_FADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_FCOM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +static int +codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FTST(codeblock_t *block, uop_t *uop) +static int +codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); - if (dest_reg != REG_EAX) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FADD(codeblock_t *block, uop_t *uop) +static int +codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *branch_offset; - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FCOM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); - if (dest_reg != REG_EAX) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FDIV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + return 0; } -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +static int +codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_offset; + uint32_t *branch_offset; - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); + host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); - return 0; + return 0; } -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +static int +codegen_JMP(codeblock_t *block, uop_t *uop) { - uint32_t *branch_offset; + host_x86_JMP(block, uop->p); - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); - host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); + return 0; +} +static int +codegen_JMP_DEST(codeblock_t *block, uop_t *uop) +{ + uop->p = host_x86_JMP_long(block); - return 0; + return 0; } -static int codegen_JMP(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { - host_x86_JMP(block, uop->p); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - return 0; -} -static int codegen_JMP_DEST(codeblock_t *block, uop_t *uop) -{ - uop->p = host_x86_JMP_long(block); - - return 0; -} - -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(src_size)) - { - host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_STACK_IMM(block, STACK_ARG2, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_STACK_IMM(block, STACK_ARG3, uop->imm_data); - return 0; -} - -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); -#endif + if (REG_IS_W(src_size)) { host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t)uop->p); - host_x86_CALL(block, loadseg); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); +# endif + return 0; } -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_long); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } - - return 0; + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); + return 0; } -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_quad); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_Q(dest_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } - - return 0; + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, uop->imm_data); + return 0; } -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + host_x86_MOV32_STACK_IMM(block, STACK_ARG2, uop->imm_data); + return 0; +} +static int +codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_STACK_IMM(block, STACK_ARG3, uop->imm_data); + return 0; +} - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); +static int +codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); +# endif + host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t) uop->p); + host_x86_CALL(block, loadseg); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } + + return 0; +} +static int +codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_x86_CALL(block, codegen_mem_load_quad); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_Q(dest_size)) { host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } - return 0; + return 0; +} +static int +codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + + return 0; } -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - return 0; + return 0; } -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_quad); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_byte); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_word); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_long); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MOV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p); - return 0; -} -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); - } - else if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - /*There is no SSE instruction to convert a 64-bit integer to a floating point value. - Instead we have to bounce the integer through memory via x87.*/ - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); - host_x87_FILDq_BASE(block, REG_ESP); - host_x87_FSTPd_BASE(block, REG_ESP); - host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); - host_x86_TEST8_REG(block, tag_reg, tag_reg); - branch_offset = host_x86_JS_long(block); - - /*There is no SSE instruction to convert a floating point value to a 64-bit integer. - Instead we have to bounce through memory via x87.*/ - host_x87_FLDCW(block, &cpu_state.new_fp_control2); - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); - host_x87_FLDd_BASE(block, REG_ESP); - host_x87_FISTPq_BASE(block, REG_ESP); - host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); - host_x87_FLDCW(block, &cpu_state.old_fp_control2); - - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_NOP(codeblock_t *block, uop_t *uop) -{ - return 0; -} - -static int codegen_OR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size) && dest_reg == src_reg) - { - host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && dest_reg == src_reg) - { - host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && dest_reg == src_reg) - { - host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PADDB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); - host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use RCPSS + iteration)*/ - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use RSQRTSS + iteration)*/ - host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); - host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); - host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); - host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_SAR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} -static int codegen_STORE_PTR_IMM_16(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV16_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} - -static int codegen_SUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_x86_TEST32_REG(block, src_reg, src_reg); - } - else if (REG_IS_W(src_size)) - { - host_x86_TEST16_REG(block, src_reg, src_reg); - } - else if (REG_IS_B(src_size)) - { - host_x86_TEST8_REG(block, src_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNS_long(block); - - return 0; -} -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_x86_TEST32_REG(block, src_reg, src_reg); - } - else if (REG_IS_W(src_size)) - { - host_x86_TEST16_REG(block, src_reg, src_reg); - } - else if (REG_IS_B(src_size)) - { - host_x86_TEST8_REG(block, src_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JS_long(block); - - return 0; -} - -static int codegen_XOR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -#ifdef DEBUG_EXTRA -static int codegen_LOG_INSTR(codeblock_t *block, uop_t *uop) -{ - if (uop->imm_data > 256*256) - fatal("LOG_INSTR %08x\n", uop->imm_data); - host_x86_INC32_ABS(block, &instr_counts[uop->imm_data]); - return 0; -} -#endif - -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, - - [UOP_JMP & UOP_MASK] = codegen_JMP, - [UOP_JMP_DEST & UOP_MASK] = codegen_JMP_DEST, - - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, - - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, - - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, - - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, - [UOP_STORE_P_IMM_16 & UOP_MASK] = codegen_STORE_PTR_IMM_16, - - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, - - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, - - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, - - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, - - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, - - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, - - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, - - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, - - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, - - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, - - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, - - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, - - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, - - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, - - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, - - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, - - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, - - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, - - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, - - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP, - -#ifdef DEBUG_EXTRA - [UOP_LOG_INSTR & UOP_MASK] = codegen_LOG_INSTR -#endif + host_x86_CALL(block, codegen_mem_store_quad); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_byte); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_word); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_long); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MOV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t) uop->p); + return 0; +} +static int +codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVSX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + /*There is no SSE instruction to convert a 64-bit integer to a floating point value. + Instead we have to bounce the integer through memory via x87.*/ + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); + host_x87_FILDq_BASE(block, REG_ESP); + host_x87_FSTPd_BASE(block, REG_ESP); + host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); + host_x86_TEST8_REG(block, tag_reg, tag_reg); + branch_offset = host_x86_JS_long(block); + + /*There is no SSE instruction to convert a floating point value to a 64-bit integer. + Instead we have to bounce through memory via x87.*/ + host_x87_FLDCW(block, &cpu_state.new_fp_control2); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); + host_x87_FLDd_BASE(block, REG_ESP); + host_x87_FISTPq_BASE(block, REG_ESP); + host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); + host_x87_FLDCW(block, &cpu_state.old_fp_control2); + + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + +static int +codegen_OR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size) && dest_reg == src_reg) { + host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && dest_reg == src_reg) { + host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && dest_reg == src_reg) { + host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); + host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RCPSS + iteration)*/ + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RSQRTSS + iteration)*/ + host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} + +static int +codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_PSUBB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_ROL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_SAR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} +static int +codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} +static int +codegen_STORE_PTR_IMM_16(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV16_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} + +static int +codegen_SUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNS_long(block); + + return 0; +} +static int +codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JS_long(block); + + return 0; +} + +static int +codegen_XOR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +# ifdef DEBUG_EXTRA +static int +codegen_LOG_INSTR(codeblock_t *block, uop_t *uop) +{ + if (uop->imm_data > 256 * 256) + fatal("LOG_INSTR %08x\n", uop->imm_data); + host_x86_INC32_ABS(block, &instr_counts[uop->imm_data]); + return 0; +} +# endif + +const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & + UOP_MASK] + = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & + UOP_MASK] + = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_JMP & + UOP_MASK] + = codegen_JMP, + [UOP_JMP_DEST & + UOP_MASK] + = codegen_JMP_DEST, + + [UOP_LOAD_SEG & + UOP_MASK] + = codegen_LOAD_SEG, + + [UOP_LOAD_FUNC_ARG_0 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3, + + [UOP_LOAD_FUNC_ARG_0_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & + UOP_MASK] + = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & + UOP_MASK] + = codegen_STORE_PTR_IMM_8, + [UOP_STORE_P_IMM_16 & + UOP_MASK] + = codegen_STORE_PTR_IMM_16, + + [UOP_MEM_LOAD_ABS & + UOP_MASK] + = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & + UOP_MASK] + = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & + UOP_MASK] + = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & + UOP_MASK] + = codegen_MEM_LOAD_DOUBLE, + + [UOP_MEM_STORE_ABS & + UOP_MASK] + = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & + UOP_MASK] + = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & + UOP_MASK] + = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & + UOP_MASK] + = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & + UOP_MASK] + = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & + UOP_MASK] + = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & + UOP_MASK] + = codegen_MEM_STORE_DOUBLE, + + [UOP_MOV & + UOP_MASK] + = codegen_MOV, + [UOP_MOV_PTR & + UOP_MASK] + = codegen_MOV_PTR, + [UOP_MOV_IMM & + UOP_MASK] + = codegen_MOV_IMM, + [UOP_MOVSX & + UOP_MASK] + = codegen_MOVSX, + [UOP_MOVZX & + UOP_MASK] + = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & + UOP_MASK] + = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & + UOP_MASK] + = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & + UOP_MASK] + = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & + UOP_MASK] + = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_16, + + [UOP_ADD & + UOP_MASK] + = codegen_ADD, + [UOP_ADD_IMM & + UOP_MASK] + = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & + UOP_MASK] + = codegen_ADD_LSHIFT, + [UOP_AND & + UOP_MASK] + = codegen_AND, + [UOP_AND_IMM & + UOP_MASK] + = codegen_AND_IMM, + [UOP_ANDN & + UOP_MASK] + = codegen_ANDN, + [UOP_OR & + UOP_MASK] + = codegen_OR, + [UOP_OR_IMM & + UOP_MASK] + = codegen_OR_IMM, + [UOP_SUB & + UOP_MASK] + = codegen_SUB, + [UOP_SUB_IMM & + UOP_MASK] + = codegen_SUB_IMM, + [UOP_XOR & + UOP_MASK] + = codegen_XOR, + [UOP_XOR_IMM & + UOP_MASK] + = codegen_XOR_IMM, + + [UOP_SAR & + UOP_MASK] + = codegen_SAR, + [UOP_SAR_IMM & + UOP_MASK] + = codegen_SAR_IMM, + [UOP_SHL & + UOP_MASK] + = codegen_SHL, + [UOP_SHL_IMM & + UOP_MASK] + = codegen_SHL_IMM, + [UOP_SHR & + UOP_MASK] + = codegen_SHR, + [UOP_SHR_IMM & + UOP_MASK] + = codegen_SHR_IMM, + [UOP_ROL & + UOP_MASK] + = codegen_ROL, + [UOP_ROL_IMM & + UOP_MASK] + = codegen_ROL_IMM, + [UOP_ROR & + UOP_MASK] + = codegen_ROR, + [UOP_ROR_IMM & + UOP_MASK] + = codegen_ROR_IMM, + + [UOP_CMP_IMM_JZ & + UOP_MASK] + = codegen_CMP_IMM_JZ, + + [UOP_CMP_JB & + UOP_MASK] + = codegen_CMP_JB, + [UOP_CMP_JNBE & + UOP_MASK] + = codegen_CMP_JNBE, + + [UOP_CMP_JNB_DEST & + UOP_MASK] + = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & + UOP_MASK] + = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & + UOP_MASK] + = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & + UOP_MASK] + = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & + UOP_MASK] + = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & + UOP_MASK] + = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & + UOP_MASK] + = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & + UOP_MASK] + = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & + UOP_MASK] + = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & + UOP_MASK] + = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & + UOP_MASK] + = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & + UOP_MASK] + = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & + UOP_MASK] + = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & + UOP_MASK] + = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & + UOP_MASK] + = codegen_FP_ENTER, + [UOP_MMX_ENTER & + UOP_MASK] + = codegen_MMX_ENTER, + + [UOP_FADD & + UOP_MASK] + = codegen_FADD, + [UOP_FDIV & + UOP_MASK] + = codegen_FDIV, + [UOP_FMUL & + UOP_MASK] + = codegen_FMUL, + [UOP_FSUB & + UOP_MASK] + = codegen_FSUB, + [UOP_FCOM & + UOP_MASK] + = codegen_FCOM, + + [UOP_FABS & + UOP_MASK] + = codegen_FABS, + [UOP_FCHS & + UOP_MASK] + = codegen_FCHS, + [UOP_FSQRT & + UOP_MASK] + = codegen_FSQRT, + [UOP_FTST & + UOP_MASK] + = codegen_FTST, + + [UOP_PACKSSWB & + UOP_MASK] + = codegen_PACKSSWB, + [UOP_PACKSSDW & + UOP_MASK] + = codegen_PACKSSDW, + [UOP_PACKUSWB & + UOP_MASK] + = codegen_PACKUSWB, + + [UOP_PADDB & + UOP_MASK] + = codegen_PADDB, + [UOP_PADDW & + UOP_MASK] + = codegen_PADDW, + [UOP_PADDD & + UOP_MASK] + = codegen_PADDD, + [UOP_PADDSB & + UOP_MASK] + = codegen_PADDSB, + [UOP_PADDSW & + UOP_MASK] + = codegen_PADDSW, + [UOP_PADDUSB & + UOP_MASK] + = codegen_PADDUSB, + [UOP_PADDUSW & + UOP_MASK] + = codegen_PADDUSW, + + [UOP_PCMPEQB & + UOP_MASK] + = codegen_PCMPEQB, + [UOP_PCMPEQW & + UOP_MASK] + = codegen_PCMPEQW, + [UOP_PCMPEQD & + UOP_MASK] + = codegen_PCMPEQD, + [UOP_PCMPGTB & + UOP_MASK] + = codegen_PCMPGTB, + [UOP_PCMPGTW & + UOP_MASK] + = codegen_PCMPGTW, + [UOP_PCMPGTD & + UOP_MASK] + = codegen_PCMPGTD, + + [UOP_PF2ID & + UOP_MASK] + = codegen_PF2ID, + [UOP_PFADD & + UOP_MASK] + = codegen_PFADD, + [UOP_PFCMPEQ & + UOP_MASK] + = codegen_PFCMPEQ, + [UOP_PFCMPGE & + UOP_MASK] + = codegen_PFCMPGE, + [UOP_PFCMPGT & + UOP_MASK] + = codegen_PFCMPGT, + [UOP_PFMAX & + UOP_MASK] + = codegen_PFMAX, + [UOP_PFMIN & + UOP_MASK] + = codegen_PFMIN, + [UOP_PFMUL & + UOP_MASK] + = codegen_PFMUL, + [UOP_PFRCP & + UOP_MASK] + = codegen_PFRCP, + [UOP_PFRSQRT & + UOP_MASK] + = codegen_PFRSQRT, + [UOP_PFSUB & + UOP_MASK] + = codegen_PFSUB, + [UOP_PI2FD & + UOP_MASK] + = codegen_PI2FD, + + [UOP_PMADDWD & + UOP_MASK] + = codegen_PMADDWD, + [UOP_PMULHW & + UOP_MASK] + = codegen_PMULHW, + [UOP_PMULLW & + UOP_MASK] + = codegen_PMULLW, + + [UOP_PSLLW_IMM & + UOP_MASK] + = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & + UOP_MASK] + = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & + UOP_MASK] + = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & + UOP_MASK] + = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & + UOP_MASK] + = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & + UOP_MASK] + = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & + UOP_MASK] + = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & + UOP_MASK] + = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & + UOP_MASK] + = codegen_PSRLQ_IMM, + + [UOP_PSUBB & + UOP_MASK] + = codegen_PSUBB, + [UOP_PSUBW & + UOP_MASK] + = codegen_PSUBW, + [UOP_PSUBD & + UOP_MASK] + = codegen_PSUBD, + [UOP_PSUBSB & + UOP_MASK] + = codegen_PSUBSB, + [UOP_PSUBSW & + UOP_MASK] + = codegen_PSUBSW, + [UOP_PSUBUSB & + UOP_MASK] + = codegen_PSUBUSB, + [UOP_PSUBUSW & + UOP_MASK] + = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & + UOP_MASK] + = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & + UOP_MASK] + = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & + UOP_MASK] + = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & + UOP_MASK] + = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & + UOP_MASK] + = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & + UOP_MASK] + = codegen_PUNPCKLDQ, + + [UOP_NOP_BARRIER & + UOP_MASK] + = codegen_NOP, + +# ifdef DEBUG_EXTRA + [UOP_LOG_INSTR & + UOP_MASK] + = codegen_LOG_INSTR +# endif }; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV8_REG_ABS(block, host_reg, p); + host_x86_MOV8_REG_ABS(block, host_reg, p); } -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV16_REG_ABS(block, host_reg, p); + host_x86_MOV16_REG_ABS(block, host_reg, p); } -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV32_REG_ABS(block, host_reg, p); + host_x86_MOV32_REG_ABS(block, host_reg, p); } -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - codegen_direct_read_32(block, host_reg, p); + codegen_direct_read_32(block, host_reg, p); } -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 0); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 0); } -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); } -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV8_ABS_REG(block, p, host_reg); + host_x86_MOV8_ABS_REG(block, p, host_reg); } -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV16_ABS_REG(block, p, host_reg); + host_x86_MOV16_ABS_REG(block, p, host_reg); } -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV32_ABS_REG(block, p, host_reg); + host_x86_MOV32_ABS_REG(block, p, host_reg); } -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); } -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV32_ABS_REG(block, p, host_reg); + host_x86_MOV32_ABS_REG(block, p, host_reg); } -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - codegen_direct_read_32_stack(block, host_reg, stack_offset); + codegen_direct_read_32_stack(block, host_reg, stack_offset); } -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); } -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); } -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); } -void codegen_set_jump_dest(codeblock_t *block, void *p) +void +codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); + *(uint32_t *) p = (uintptr_t) &block_write_data[block_pos] - ((uintptr_t) p + 4); } -void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) +void +codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) { - host_x86_MOV8_ABS_IMM(block, p, imm_data); + host_x86_MOV8_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) +void +codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) { - host_x86_MOV16_ABS_IMM(block, p, imm_data); + host_x86_MOV16_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) +void +codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) { - host_x86_MOV32_ABS_IMM(block, p, imm_data); + host_x86_MOV32_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) +void +codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) { - host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); + host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); } #endif diff --git a/src/codegen_new/codegen_block.c b/src/codegen_new/codegen_block.c index e2aaddb5c..c519b34d2 100644 --- a/src/codegen_new/codegen_block.c +++ b/src/codegen_new/codegen_block.c @@ -21,39 +21,39 @@ uint8_t *block_write_data = NULL; -int codegen_flat_ds, codegen_flat_ss; -int mmx_ebx_ecx_loaded; -int codegen_flags_changed = 0; -int codegen_fpu_entered = 0; -int codegen_mmx_entered = 0; -int codegen_fpu_loaded_iq[8]; -x86seg *op_ea_seg; -int op_ssegs; +int codegen_flat_ds, codegen_flat_ss; +int mmx_ebx_ecx_loaded; +int codegen_flags_changed = 0; +int codegen_fpu_entered = 0; +int codegen_mmx_entered = 0; +int codegen_fpu_loaded_iq[8]; +x86seg *op_ea_seg; +int op_ssegs; uint32_t op_old_pc; uint32_t recomp_page = -1; -int block_current = 0; +int block_current = 0; static int block_num; -int block_pos; +int block_pos; uint32_t codegen_endpc; -int codegen_block_cycles; +int codegen_block_cycles; static int codegen_block_ins; static int codegen_block_full_ins; static uint32_t last_op32; -static x86seg *last_ea_seg; -static int last_ssegs; +static x86seg *last_ea_seg; +static int last_ssegs; #ifdef DEBUG_EXTRA -uint32_t instr_counts[256*256]; +uint32_t instr_counts[256 * 256]; #endif static uint16_t block_free_list; -static void delete_block(codeblock_t *block); -static void delete_dirty_block(codeblock_t *block); +static void delete_block(codeblock_t *block); +static void delete_dirty_block(codeblock_t *block); /*Temporary list of code blocks that have recently been evicted. This allows for some historical state to be kept when a block is the target of self-modifying @@ -62,830 +62,793 @@ static void delete_dirty_block(codeblock_t *block); The size of this list is limited to DIRTY_LIST_MAX_SIZE blocks. When this is exceeded the oldest entry will be moved to the free list.*/ static uint16_t block_dirty_list_head, block_dirty_list_tail; -static int dirty_list_size = 0; +static int dirty_list_size = 0; #define DIRTY_LIST_MAX_SIZE 64 -static void block_free_list_add(codeblock_t *block) +static void +block_free_list_add(codeblock_t *block) { #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("block_free_list_add: block=%p in dirty list\n", block); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("block_free_list_add: block=%p in dirty list\n", block); #endif - if (block_free_list) - block->next = block_free_list; - else - block->next = 0; - block_free_list = get_block_nr(block); - block->flags = CODEBLOCK_IN_FREE_LIST; + if (block_free_list) + block->next = block_free_list; + else + block->next = 0; + block_free_list = get_block_nr(block); + block->flags = CODEBLOCK_IN_FREE_LIST; } -static void block_dirty_list_add(codeblock_t *block) +static void +block_dirty_list_add(codeblock_t *block) { #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("block_dirty_list_add: block=%p already in dirty list\n", block); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("block_dirty_list_add: block=%p already in dirty list\n", block); #endif - if (block_dirty_list_head != BLOCK_INVALID) - { - codeblock_t *old_head = &codeblock[block_dirty_list_head]; + if (block_dirty_list_head != BLOCK_INVALID) { + codeblock_t *old_head = &codeblock[block_dirty_list_head]; - block->next = block_dirty_list_head; - block->prev = BLOCK_INVALID; - block_dirty_list_head = old_head->prev = get_block_nr(block); - } - else - { - /*List empty*/ - block->prev = block->next = BLOCK_INVALID; - block_dirty_list_head = block_dirty_list_tail = get_block_nr(block); - } - block->flags |= CODEBLOCK_IN_DIRTY_LIST; - dirty_list_size++; - if (dirty_list_size > DIRTY_LIST_MAX_SIZE) - { - /*Evict oldest block to the free list*/ - codeblock_t *evict_block = &codeblock[block_dirty_list_tail]; + block->next = block_dirty_list_head; + block->prev = BLOCK_INVALID; + block_dirty_list_head = old_head->prev = get_block_nr(block); + } else { + /*List empty*/ + block->prev = block->next = BLOCK_INVALID; + block_dirty_list_head = block_dirty_list_tail = get_block_nr(block); + } + block->flags |= CODEBLOCK_IN_DIRTY_LIST; + dirty_list_size++; + if (dirty_list_size > DIRTY_LIST_MAX_SIZE) { + /*Evict oldest block to the free list*/ + codeblock_t *evict_block = &codeblock[block_dirty_list_tail]; #ifndef RELEASE_BUILD - if (!(evict_block->flags & CODEBLOCK_IN_DIRTY_LIST)) - fatal("block_dirty_list_add: evict_block=%p %x %x not in dirty list\n", evict_block, evict_block->phys, evict_block->flags); - if (!block_dirty_list_tail) - fatal("block_dirty_list_add - !block_dirty_list_tail\n"); - if (evict_block->prev == BLOCK_INVALID) - fatal("block_dirty_list_add - evict_block->prev == BLOCK_INVALID\n"); + if (!(evict_block->flags & CODEBLOCK_IN_DIRTY_LIST)) + fatal("block_dirty_list_add: evict_block=%p %x %x not in dirty list\n", evict_block, evict_block->phys, evict_block->flags); + if (!block_dirty_list_tail) + fatal("block_dirty_list_add - !block_dirty_list_tail\n"); + if (evict_block->prev == BLOCK_INVALID) + fatal("block_dirty_list_add - evict_block->prev == BLOCK_INVALID\n"); #endif - block_dirty_list_tail = evict_block->prev; - codeblock[evict_block->prev].next = BLOCK_INVALID; - - dirty_list_size--; - evict_block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; - delete_dirty_block(evict_block); - } -} - -static void block_dirty_list_remove(codeblock_t *block) -{ - codeblock_t *prev_block = &codeblock[block->prev]; - codeblock_t *next_block = &codeblock[block->next]; - -#ifndef RELEASE_BUILD - if (!(block->flags & CODEBLOCK_IN_DIRTY_LIST)) - fatal("block_dirty_list_remove: block=%p not in dirty list\n", block); -#endif - - /*Is block head of list*/ - if (block->prev == BLOCK_INVALID) - block_dirty_list_head = block->next; - else - prev_block->next = block->next; - - /*Is block tail of list?*/ - if (block->next == BLOCK_INVALID) - block_dirty_list_tail = block->prev; - else - next_block->prev = block->prev; + block_dirty_list_tail = evict_block->prev; + codeblock[evict_block->prev].next = BLOCK_INVALID; dirty_list_size--; + evict_block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; + delete_dirty_block(evict_block); + } +} + +static void +block_dirty_list_remove(codeblock_t *block) +{ + codeblock_t *prev_block = &codeblock[block->prev]; + codeblock_t *next_block = &codeblock[block->next]; + #ifndef RELEASE_BUILD - if (dirty_list_size < 0) - fatal("remove - dirty_list_size < 0!\n"); + if (!(block->flags & CODEBLOCK_IN_DIRTY_LIST)) + fatal("block_dirty_list_remove: block=%p not in dirty list\n", block); #endif - block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; -} -int codegen_purge_purgable_list() -{ - if (purgable_page_list_head) - { - page_t *page = &pages[purgable_page_list_head]; + /*Is block head of list*/ + if (block->prev == BLOCK_INVALID) + block_dirty_list_head = block->next; + else + prev_block->next = block->next; - if (page->code_present_mask & page->dirty_mask) - { - codegen_check_flush(page, page->dirty_mask, purgable_page_list_head << 12); + /*Is block tail of list?*/ + if (block->next == BLOCK_INVALID) + block_dirty_list_tail = block->prev; + else + next_block->prev = block->prev; - if (block_free_list) - return 1; - } - } - return 0; -} - -static codeblock_t *block_free_list_get() -{ - codeblock_t *block = NULL; - - while (!block_free_list) - { - /*Free list is empty, check the dirty list*/ - if (block_dirty_list_tail) - { + dirty_list_size--; #ifndef RELEASE_BUILD - if (dirty_list_size <= 0) - fatal("get - dirty_list_size <= 0!\n"); + if (dirty_list_size < 0) + fatal("remove - dirty_list_size < 0!\n"); #endif - /*Reuse oldest block*/ - block = &codeblock[block_dirty_list_tail]; - - block_dirty_list_tail = block->prev; - if (block->prev == BLOCK_INVALID) - block_dirty_list_head = BLOCK_INVALID; - else - codeblock[block->prev].next = BLOCK_INVALID; - dirty_list_size--; - block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; - delete_dirty_block(block); - block_free_list = get_block_nr(block); - break; - } - /*Free list is empty - free up a block*/ - if (!codegen_purge_purgable_list()) - codegen_delete_random_block(0); - } - - block = &codeblock[block_free_list]; - block_free_list = block->next; - block->flags &= ~CODEBLOCK_IN_FREE_LIST; - block->next = 0; - return block; + block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; } -void codegen_init() +int +codegen_purge_purgable_list(void) { - int c; + if (purgable_page_list_head) { + page_t *page = &pages[purgable_page_list_head]; - codegen_allocator_init(); + if (page->code_present_mask & page->dirty_mask) { + codegen_check_flush(page, page->dirty_mask, purgable_page_list_head << 12); - codegen_backend_init(); - block_free_list = 0; - for (c = 0; c < BLOCK_SIZE; c++) - block_free_list_add(&codeblock[c]); - block_dirty_list_head = block_dirty_list_tail = 0; - dirty_list_size = 0; + if (block_free_list) + return 1; + } + } + return 0; +} + +static codeblock_t * +block_free_list_get(void) +{ + codeblock_t *block = NULL; + + while (!block_free_list) { + /*Free list is empty, check the dirty list*/ + if (block_dirty_list_tail) { +#ifndef RELEASE_BUILD + if (dirty_list_size <= 0) + fatal("get - dirty_list_size <= 0!\n"); +#endif + /*Reuse oldest block*/ + block = &codeblock[block_dirty_list_tail]; + + block_dirty_list_tail = block->prev; + if (block->prev == BLOCK_INVALID) + block_dirty_list_head = BLOCK_INVALID; + else + codeblock[block->prev].next = BLOCK_INVALID; + dirty_list_size--; + block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; + delete_dirty_block(block); + block_free_list = get_block_nr(block); + break; + } + /*Free list is empty - free up a block*/ + if (!codegen_purge_purgable_list()) + codegen_delete_random_block(0); + } + + block = &codeblock[block_free_list]; + block_free_list = block->next; + block->flags &= ~CODEBLOCK_IN_FREE_LIST; + block->next = 0; + return block; +} + +void +codegen_init(void) +{ + int c; + + codegen_allocator_init(); + + codegen_backend_init(); + block_free_list = 0; + for (c = 0; c < BLOCK_SIZE; c++) + block_free_list_add(&codeblock[c]); + block_dirty_list_head = block_dirty_list_tail = 0; + dirty_list_size = 0; #ifdef DEBUG_EXTRA - memset(instr_counts, 0, sizeof(instr_counts)); + memset(instr_counts, 0, sizeof(instr_counts)); #endif } -void codegen_close() +void +codegen_close(void) { #ifdef DEBUG_EXTRA - pclog("Instruction counts :\n"); - while (1) - { - int c; - uint32_t highest_num = 0, highest_idx = 0; + pclog("Instruction counts :\n"); + while (1) { + int c; + uint32_t highest_num = 0, highest_idx = 0; - for (c = 0; c < 256*256; c++) - { - if (instr_counts[c] > highest_num) - { - highest_num = instr_counts[c]; - highest_idx = c; - } - } - if (!highest_num) - break; - - instr_counts[highest_idx] = 0; - if (highest_idx > 256) - pclog(" %02x %02x = %u\n", highest_idx >> 8, highest_idx & 0xff, highest_num); - else - pclog(" %02x = %u\n", highest_idx & 0xff, highest_num); + for (c = 0; c < 256 * 256; c++) { + if (instr_counts[c] > highest_num) { + highest_num = instr_counts[c]; + highest_idx = c; + } } -#endif -} + if (!highest_num) + break; -void codegen_reset() -{ - int c; - - for (c = 1; c < BLOCK_SIZE; c++) - { - codeblock_t *block = &codeblock[c]; - - if (block->pc != BLOCK_PC_INVALID) - { - block->phys = 0; - block->phys_2 = 0; - delete_block(block); - } - } - - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(uint16_t)); - mem_reset_page_blocks(); - - block_free_list = 0; - for (c = 0; c < BLOCK_SIZE; c++) - { - codeblock[c].pc = BLOCK_PC_INVALID; - block_free_list_add(&codeblock[c]); - } -} - -void dump_block() -{ -/* codeblock_t *block = pages[0x119000 >> 12].block; - - pclog("dump_block:\n"); - while (block) - { - uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); - uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); - pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); - if (!block->pc) - fatal("Dead PC=0\n"); - - block = block->next; - } - pclog("dump_block done\n");*/ -} - -static void add_to_block_list(codeblock_t *block) -{ - uint16_t block_prev_nr = pages[block->phys >> 12].block; - uint16_t block_nr = get_block_nr(block); - -#ifndef RELEASE_BUILD - if (!block->page_mask) - fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask,block->page_mask2); -#endif - - if (block_prev_nr) - { - block->next = block_prev_nr; - codeblock[block_prev_nr].prev = block_nr; - pages[block->phys >> 12].block = block_nr; - } + instr_counts[highest_idx] = 0; + if (highest_idx > 256) + pclog(" %02x %02x = %u\n", highest_idx >> 8, highest_idx & 0xff, highest_num); else - { - block->next = BLOCK_INVALID; - pages[block->phys >> 12].block = block_nr; - } + pclog(" %02x = %u\n", highest_idx & 0xff, highest_num); + } +#endif +} +void +codegen_reset(void) +{ + int c; + + for (c = 1; c < BLOCK_SIZE; c++) { + codeblock_t *block = &codeblock[c]; + + if (block->pc != BLOCK_PC_INVALID) { + block->phys = 0; + block->phys_2 = 0; + delete_block(block); + } + } + + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(uint16_t)); + mem_reset_page_blocks(); + + block_free_list = 0; + for (c = 0; c < BLOCK_SIZE; c++) { + codeblock[c].pc = BLOCK_PC_INVALID; + block_free_list_add(&codeblock[c]); + } +} + +void +dump_block(void) +{ + /* codeblock_t *block = pages[0x119000 >> 12].block; + + pclog("dump_block:\n"); + while (block) + { + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); + pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); + if (!block->pc) + fatal("Dead PC=0\n"); + + block = block->next; + } + pclog("dump_block done\n");*/ +} + +static void +add_to_block_list(codeblock_t *block) +{ + uint16_t block_prev_nr = pages[block->phys >> 12].block; + uint16_t block_nr = get_block_nr(block); + +#ifndef RELEASE_BUILD + if (!block->page_mask) + fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask, block->page_mask2); +#endif + + if (block_prev_nr) { + block->next = block_prev_nr; + codeblock[block_prev_nr].prev = block_nr; + pages[block->phys >> 12].block = block_nr; + } else { + block->next = BLOCK_INVALID; + pages[block->phys >> 12].block = block_nr; + } + + if (block->next) { +#ifndef RELEASE_BUILD + if (codeblock[block->next].pc == BLOCK_PC_INVALID) + fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *) &codeblock[block->next], (void *) codeblock, block_current, block_pos); +#endif + } + + if (block->page_mask2) { + block->flags |= CODEBLOCK_HAS_PAGE2; + + block_prev_nr = pages[block->phys_2 >> 12].block_2; + + if (block_prev_nr) { + block->next_2 = block_prev_nr; + codeblock[block_prev_nr].prev_2 = block_nr; + pages[block->phys_2 >> 12].block_2 = block_nr; + } else { + block->next_2 = BLOCK_INVALID; + pages[block->phys_2 >> 12].block_2 = block_nr; + } + } +} + +static void +remove_from_block_list(codeblock_t *block, uint32_t pc) +{ + if (!block->page_mask) + return; +#ifndef RELEASE_BUILD + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("remove_from_block_list: in dirty list\n"); +#endif + if (block->prev) { + codeblock[block->prev].next = block->next; if (block->next) - { + codeblock[block->next].prev = block->prev; + } else { + pages[block->phys >> 12].block = block->next; + if (block->next) + codeblock[block->next].prev = BLOCK_INVALID; + else + mem_flush_write_page(block->phys, 0); + } + + if (!(block->flags & CODEBLOCK_HAS_PAGE2)) { #ifndef RELEASE_BUILD - if (codeblock[block->next].pc == BLOCK_PC_INVALID) - fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)&codeblock[block->next], (void *)codeblock, block_current, block_pos); + if (block->prev_2 || block->next_2) + fatal("Invalid block_2 %x %p %08x\n", block->flags, block, block->phys); #endif - } + return; + } + block->flags &= ~CODEBLOCK_HAS_PAGE2; - if (block->page_mask2) - { - block->flags |= CODEBLOCK_HAS_PAGE2; - - block_prev_nr = pages[block->phys_2 >> 12].block_2; - - if (block_prev_nr) - { - block->next_2 = block_prev_nr; - codeblock[block_prev_nr].prev_2 = block_nr; - pages[block->phys_2 >> 12].block_2 = block_nr; - } - else - { - block->next_2 = BLOCK_INVALID; - pages[block->phys_2 >> 12].block_2 = block_nr; - } - } + if (block->prev_2) { + codeblock[block->prev_2].next_2 = block->next_2; + if (block->next_2) + codeblock[block->next_2].prev_2 = block->prev_2; + } else { + pages[block->phys_2 >> 12].block_2 = block->next_2; + if (block->next_2) + codeblock[block->next_2].prev_2 = BLOCK_INVALID; + else + mem_flush_write_page(block->phys_2, 0); + } } -static void remove_from_block_list(codeblock_t *block, uint32_t pc) +static void +invalidate_block(codeblock_t *block) { - if (!block->page_mask) - return; -#ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("remove_from_block_list: in dirty list\n"); -#endif - if (block->prev) - { - codeblock[block->prev].next = block->next; - if (block->next) - codeblock[block->next].prev = block->prev; - } - else - { - pages[block->phys >> 12].block = block->next; - if (block->next) - codeblock[block->next].prev = BLOCK_INVALID; - else - mem_flush_write_page(block->phys, 0); - } + uint32_t old_pc = block->pc; - if (!(block->flags & CODEBLOCK_HAS_PAGE2)) - { #ifndef RELEASE_BUILD - if (block->prev_2 || block->next_2) - fatal("Invalid block_2 %x %p %08x\n", block->flags, block, block->phys); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("invalidate_block: already in dirty list\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Invalidating deleted block\n"); #endif - return; - } - block->flags &= ~CODEBLOCK_HAS_PAGE2; - - if (block->prev_2) - { - codeblock[block->prev_2].next_2 = block->next_2; - if (block->next_2) - codeblock[block->next_2].prev_2 = block->prev_2; - } - else - { - pages[block->phys_2 >> 12].block_2 = block->next_2; - if (block->next_2) - codeblock[block->next_2].prev_2 = BLOCK_INVALID; - else - mem_flush_write_page(block->phys_2, 0); - } + remove_from_block_list(block, old_pc); + block_dirty_list_add(block); + if (block->head_mem_block) + codegen_allocator_free(block->head_mem_block); + block->head_mem_block = NULL; } -static void invalidate_block(codeblock_t *block) +static void +delete_block(codeblock_t *block) { - uint32_t old_pc = block->pc; + uint32_t old_pc = block->pc; + + if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) + codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("invalidate_block: already in dirty list\n"); - if (block->pc == BLOCK_PC_INVALID) - fatal("Invalidating deleted block\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Deleting deleted block\n"); #endif + block->pc = BLOCK_PC_INVALID; + + codeblock_tree_delete(block); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block_dirty_list_remove(block); + else remove_from_block_list(block, old_pc); - block_dirty_list_add(block); - if (block->head_mem_block) - codegen_allocator_free(block->head_mem_block); - block->head_mem_block = NULL; + if (block->head_mem_block) + codegen_allocator_free(block->head_mem_block); + block->head_mem_block = NULL; + block_free_list_add(block); } -static void delete_block(codeblock_t *block) +static void +delete_dirty_block(codeblock_t *block) { - uint32_t old_pc = block->pc; - - if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) - codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; + if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) + codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; #ifndef RELEASE_BUILD - if (block->pc == BLOCK_PC_INVALID) - fatal("Deleting deleted block\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Deleting deleted block\n"); #endif - block->pc = BLOCK_PC_INVALID; + block->pc = BLOCK_PC_INVALID; - codeblock_tree_delete(block); - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block_dirty_list_remove(block); - else - remove_from_block_list(block, old_pc); - if (block->head_mem_block) - codegen_allocator_free(block->head_mem_block); - block->head_mem_block = NULL; - block_free_list_add(block); + codeblock_tree_delete(block); + block_free_list_add(block); } -static void delete_dirty_block(codeblock_t *block) +void +codegen_delete_block(codeblock_t *block) { - if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) - codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; - -#ifndef RELEASE_BUILD - if (block->pc == BLOCK_PC_INVALID) - fatal("Deleting deleted block\n"); -#endif - block->pc = BLOCK_PC_INVALID; - - codeblock_tree_delete(block); - block_free_list_add(block); + if (block->pc != BLOCK_PC_INVALID) + delete_block(block); } -void codegen_delete_block(codeblock_t *block) +void +codegen_delete_random_block(int required_mem_block) { - if (block->pc != BLOCK_PC_INVALID) + int block_nr = rand() & BLOCK_MASK; + + while (1) { + if (block_nr && block_nr != block_current) { + codeblock_t *block = &codeblock[block_nr]; + + if (block->pc != BLOCK_PC_INVALID && (!required_mem_block || block->head_mem_block)) { delete_block(block); + return; + } + } + block_nr = (block_nr + 1) & BLOCK_MASK; + } } -void codegen_delete_random_block(int required_mem_block) +void +codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) { - int block_nr = rand() & BLOCK_MASK; + uint16_t block_nr = page->block; + int remove_from_evict_list = 0; + int c; - while (1) - { - if (block_nr && block_nr != block_current) - { - codeblock_t *block = &codeblock[block_nr]; + while (block_nr) { + codeblock_t *block = &codeblock[block_nr]; + uint16_t next_block = block->next; - if (block->pc != BLOCK_PC_INVALID && (!required_mem_block || block->head_mem_block)) - { - delete_block(block); - return; - } - } - block_nr = (block_nr + 1) & BLOCK_MASK; + if (*block->dirty_mask & block->page_mask) { + invalidate_block(block); } +#ifndef RELEASE_BUILD + if (block_nr == next_block) + fatal("Broken 1\n"); +#endif + block_nr = next_block; + } + + block_nr = page->block_2; + + while (block_nr) { + codeblock_t *block = &codeblock[block_nr]; + uint16_t next_block = block->next_2; + + if (*block->dirty_mask2 & block->page_mask2) { + invalidate_block(block); + } +#ifndef RELEASE_BUILD + if (block_nr == next_block) + fatal("Broken 2\n"); +#endif + block_nr = next_block; + } + + if (page->code_present_mask & page->dirty_mask) + remove_from_evict_list = 1; + page->code_present_mask &= ~page->dirty_mask; + page->dirty_mask = 0; + + for (c = 0; c < 64; c++) { + if (page->byte_code_present_mask[c] & page->byte_dirty_mask[c]) + remove_from_evict_list = 0; + page->byte_code_present_mask[c] &= ~page->byte_dirty_mask[c]; + page->byte_dirty_mask[c] = 0; + } + if (remove_from_evict_list) + page_remove_from_evict_list(page); } -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) +void +codegen_block_init(uint32_t phys_addr) { - uint16_t block_nr = page->block; - int remove_from_evict_list = 0; - int c; + codeblock_t *block; + page_t *page = &pages[phys_addr >> 12]; - while (block_nr) - { - codeblock_t *block = &codeblock[block_nr]; - uint16_t next_block = block->next; - - if (*block->dirty_mask & block->page_mask) - { - invalidate_block(block); - } + if (!page->block) + mem_flush_write_page(phys_addr, cs + cpu_state.pc); + block = block_free_list_get(); #ifndef RELEASE_BUILD - if (block_nr == next_block) - fatal("Broken 1\n"); + if (!block) + fatal("codegen_block_init: block_free_list_get() returned NULL\n"); #endif - block_nr = next_block; - } + block_current = get_block_nr(block); - block_nr = page->block_2; + block_num = HASH(phys_addr); + codeblock_hash[block_num] = block_current; - while (block_nr) - { - codeblock_t *block = &codeblock[block_nr]; - uint16_t next_block = block->next_2; + block->ins = 0; + block->pc = cs + cpu_state.pc; + block->_cs = cs; + block->phys = phys_addr; + block->dirty_mask = &page->dirty_mask; + block->dirty_mask2 = NULL; + block->next = block->prev = BLOCK_INVALID; + block->next_2 = block->prev_2 = BLOCK_INVALID; + block->page_mask = block->page_mask2 = 0; + block->flags = CODEBLOCK_STATIC_TOP; + block->status = cpu_cur_status; - if (*block->dirty_mask2 & block->page_mask2) - { - invalidate_block(block); - } -#ifndef RELEASE_BUILD - if (block_nr == next_block) - fatal("Broken 2\n"); -#endif - block_nr = next_block; - } - - if (page->code_present_mask & page->dirty_mask) - remove_from_evict_list = 1; - page->code_present_mask &= ~page->dirty_mask; - page->dirty_mask = 0; - - for (c = 0; c < 64; c++) - { - if (page->byte_code_present_mask[c] & page->byte_dirty_mask[c]) - remove_from_evict_list = 0; - page->byte_code_present_mask[c] &= ~page->byte_dirty_mask[c]; - page->byte_dirty_mask[c] = 0; - } - if (remove_from_evict_list) - page_remove_from_evict_list(page); -} - -void codegen_block_init(uint32_t phys_addr) -{ - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; - - if (!page->block) - mem_flush_write_page(phys_addr, cs+cpu_state.pc); - block = block_free_list_get(); -#ifndef RELEASE_BUILD - if (!block) - fatal("codegen_block_init: block_free_list_get() returned NULL\n"); -#endif - block_current = get_block_nr(block); - - block_num = HASH(phys_addr); - codeblock_hash[block_num] = block_current; - - block->ins = 0; - block->pc = cs + cpu_state.pc; - block->_cs = cs; - block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask; - block->dirty_mask2 = NULL; - block->next = block->prev = BLOCK_INVALID; - block->next_2 = block->prev_2 = BLOCK_INVALID; - block->page_mask = block->page_mask2 = 0; - block->flags = CODEBLOCK_STATIC_TOP; - block->status = cpu_cur_status; - - recomp_page = block->phys & ~0xfff; - codeblock_tree_add(block); + recomp_page = block->phys & ~0xfff; + codeblock_tree_add(block); } static ir_data_t *ir_data; -ir_data_t *codegen_get_ir_data() +ir_data_t * +codegen_get_ir_data(void) { - return ir_data; + return ir_data; } -void codegen_block_start_recompile(codeblock_t *block) +void +codegen_block_start_recompile(codeblock_t *block) { - page_t *page = &pages[block->phys >> 12]; + page_t *page = &pages[block->phys >> 12]; - if (!page->block) - mem_flush_write_page(block->phys, cs+cpu_state.pc); + if (!page->block) + mem_flush_write_page(block->phys, cs + cpu_state.pc); - block_num = HASH(block->phys); - block_current = get_block_nr(block);//block->pnt; + block_num = HASH(block->phys); + block_current = get_block_nr(block); // block->pnt; #ifndef RELEASE_BUILD - if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) - fatal("Recompile to used block!\n"); + if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) + fatal("Recompile to used block!\n"); #endif - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block->status = cpu_cur_status; + block->status = cpu_cur_status; - block->page_mask = block->page_mask2 = 0; - block->ins = 0; + block->page_mask = block->page_mask2 = 0; + block->ins = 0; - cpu_block_end = 0; + cpu_block_end = 0; - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; - codegen_block_cycles = 0; - codegen_timing_block_start(); + codegen_block_cycles = 0; + codegen_timing_block_start(); - codegen_block_ins = 0; - codegen_block_full_ins = 0; + codegen_block_ins = 0; + codegen_block_full_ins = 0; - recomp_page = block->phys & ~0xfff; + recomp_page = block->phys & ~0xfff; - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; + codegen_flags_changed = 0; + codegen_fpu_entered = 0; + codegen_mmx_entered = 0; - codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = - codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; + codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; - block->TOP = cpu_state.TOP & 7; - block->flags |= CODEBLOCK_WAS_RECOMPILED; + block->TOP = cpu_state.TOP & 7; + block->flags |= CODEBLOCK_WAS_RECOMPILED; - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); - if (block->flags & CODEBLOCK_BYTE_MASK) - { - block->dirty_mask = &page->byte_dirty_mask[(block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK]; - block->dirty_mask2 = NULL; - } + if (block->flags & CODEBLOCK_BYTE_MASK) { + block->dirty_mask = &page->byte_dirty_mask[(block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK]; + block->dirty_mask2 = NULL; + } - ir_data = codegen_ir_init(); - ir_data->block = block; - codegen_reg_reset(); - codegen_accumulate_reset(); - codegen_generate_reset(); + ir_data = codegen_ir_init(); + ir_data->block = block; + codegen_reg_reset(); + codegen_accumulate_reset(); + codegen_generate_reset(); } - -void codegen_block_remove() +void +codegen_block_remove(void) { - codeblock_t *block = &codeblock[block_current]; + codeblock_t *block = &codeblock[block_current]; - delete_block(block); + delete_block(block); - recomp_page = -1; + recomp_page = -1; } -void codegen_block_generate_end_mask_recompile() +void +codegen_block_generate_end_mask_recompile(void) { - codeblock_t *block = &codeblock[block_current]; - page_t *p; + codeblock_t *block = &codeblock[block_current]; + page_t *p; - p = &pages[block->phys >> 12]; - if (block->flags & CODEBLOCK_BYTE_MASK) - { - int offset = (block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + p = &pages[block->phys >> 12]; + if (block->flags & CODEBLOCK_BYTE_MASK) { + int offset = (block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - p->byte_code_present_mask[offset] |= block->page_mask; - } - else - p->code_present_mask |= block->page_mask; - - if ((*(block->dirty_mask) & block->page_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - - block->phys_2 = -1; - block->next_2 = block->prev_2 = BLOCK_INVALID; - if (block->page_mask2) - { - block->phys_2 = get_phys_noabrt(codegen_endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; - - if (block->flags & CODEBLOCK_BYTE_MASK) - { - int offset = (block->phys_2 >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - - page_2->byte_code_present_mask[offset] |= block->page_mask2; - block->dirty_mask2 = &page_2->byte_dirty_mask[offset]; - } - else - { - page_2->code_present_mask |= block->page_mask2; - block->dirty_mask2 = &page_2->dirty_mask; - } - if (((*block->dirty_mask2) & block->page_mask2) && !page_in_evict_list(page_2)) - page_add_to_evict_list(page_2); - - if (!pages[block->phys_2 >> 12].block_2) - mem_flush_write_page(block->phys_2, codegen_endpc); - -#ifndef RELEASE_BUILD - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) - fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); - } -#endif - } - else - { - /*Second page not present. page_mask2 is most likely set only because - the recompiler didn't know how long the last instruction was, so - clear it*/ - block->page_mask2 = 0; - } - } - - recomp_page = -1; -} - -void codegen_block_generate_end_mask_mark() -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; - page_t *p; - -#ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_BYTE_MASK) - fatal("codegen_block_generate_end_mask2() - BYTE_MASK\n"); -#endif - - block->page_mask = 0; - start_pc = (block->pc & 0xfff) & ~63; - if ((block->pc ^ codegen_endpc) & ~0xfff) - end_pc = 0xfff & ~63; - else - end_pc = (codegen_endpc & 0xfff) & ~63; - if (end_pc < start_pc) - end_pc = 0xfff; - start_pc >>= PAGE_MASK_SHIFT; - end_pc >>= PAGE_MASK_SHIFT; - - for (; start_pc <= end_pc; start_pc++) - { - block->page_mask |= ((uint64_t)1 << start_pc); - } - - p = &pages[block->phys >> 12]; + p->byte_code_present_mask[offset] |= block->page_mask; + } else p->code_present_mask |= block->page_mask; - if ((p->dirty_mask & block->page_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - block->phys_2 = -1; - block->page_mask2 = 0; - block->next_2 = block->prev_2 = BLOCK_INVALID; - if ((block->pc ^ codegen_endpc) & ~0xfff) - { - block->phys_2 = get_phys_noabrt(codegen_endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; + if ((*(block->dirty_mask) & block->page_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); - start_pc = 0; - end_pc = (codegen_endpc & 0xfff) >> PAGE_MASK_SHIFT; - for (; start_pc <= end_pc; start_pc++) - block->page_mask2 |= ((uint64_t)1 << start_pc); + block->phys_2 = -1; + block->next_2 = block->prev_2 = BLOCK_INVALID; + if (block->page_mask2) { + block->phys_2 = get_phys_noabrt(codegen_endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; - page_2->code_present_mask |= block->page_mask2; - if ((page_2->dirty_mask & block->page_mask2) && !page_in_evict_list(page_2)) - page_add_to_evict_list(page_2); + if (block->flags & CODEBLOCK_BYTE_MASK) { + int offset = (block->phys_2 >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - if (!pages[block->phys_2 >> 12].block_2) - mem_flush_write_page(block->phys_2, codegen_endpc); + page_2->byte_code_present_mask[offset] |= block->page_mask2; + block->dirty_mask2 = &page_2->byte_dirty_mask[offset]; + } else { + page_2->code_present_mask |= block->page_mask2; + block->dirty_mask2 = &page_2->dirty_mask; + } + if (((*block->dirty_mask2) & block->page_mask2) && !page_in_evict_list(page_2)) + page_add_to_evict_list(page_2); + + if (!pages[block->phys_2 >> 12].block_2) + mem_flush_write_page(block->phys_2, codegen_endpc); #ifndef RELEASE_BUILD - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) - fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); - } + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *) &codeblock[block->next_2]); + } #endif - block->dirty_mask2 = &page_2->dirty_mask; - } - else - { - /*Second page not present. page_mask2 is most likely set only because - the recompiler didn't know how long the last instruction was, so - clear it*/ - block->page_mask2 = 0; - } + } else { + /*Second page not present. page_mask2 is most likely set only because + the recompiler didn't know how long the last instruction was, so + clear it*/ + block->page_mask2 = 0; } + } - recomp_page = -1; + recomp_page = -1; } -void codegen_block_end() +void +codegen_block_generate_end_mask_mark(void) { - codeblock_t *block = &codeblock[block_current]; + codeblock_t *block = &codeblock[block_current]; + uint32_t start_pc; + uint32_t end_pc; + page_t *p; - codegen_block_generate_end_mask_mark(); - add_to_block_list(block); -} +#ifndef RELEASE_BUILD + if (block->flags & CODEBLOCK_BYTE_MASK) + fatal("codegen_block_generate_end_mask2() - BYTE_MASK\n"); +#endif -void codegen_block_end_recompile(codeblock_t *block) -{ - codegen_timing_block_end(); - codegen_accumulate(ir_data, ACCREG_cycles, -codegen_block_cycles); + block->page_mask = 0; + start_pc = (block->pc & 0xfff) & ~63; + if ((block->pc ^ codegen_endpc) & ~0xfff) + end_pc = 0xfff & ~63; + else + end_pc = (codegen_endpc & 0xfff) & ~63; + if (end_pc < start_pc) + end_pc = 0xfff; + start_pc >>= PAGE_MASK_SHIFT; + end_pc >>= PAGE_MASK_SHIFT; - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block_dirty_list_remove(block); - else - remove_from_block_list(block, block->pc); - block->next = block->prev = BLOCK_INVALID; - block->next_2 = block->prev_2 = BLOCK_INVALID; - codegen_block_generate_end_mask_recompile(); - add_to_block_list(block); + for (; start_pc <= end_pc; start_pc++) { + block->page_mask |= ((uint64_t) 1 << start_pc); + } - if (!(block->flags & CODEBLOCK_HAS_FPU)) - block->flags &= ~CODEBLOCK_STATIC_TOP; + p = &pages[block->phys >> 12]; + p->code_present_mask |= block->page_mask; + if ((p->dirty_mask & block->page_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); - codegen_accumulate_flush(ir_data); - codegen_ir_compile(ir_data, block); -} + block->phys_2 = -1; + block->page_mask2 = 0; + block->next_2 = block->prev_2 = BLOCK_INVALID; + if ((block->pc ^ codegen_endpc) & ~0xfff) { + block->phys_2 = get_phys_noabrt(codegen_endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; -void codegen_flush() -{ - return; -} + start_pc = 0; + end_pc = (codegen_endpc & 0xfff) >> PAGE_MASK_SHIFT; + for (; start_pc <= end_pc; start_pc++) + block->page_mask2 |= ((uint64_t) 1 << start_pc); -void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len) -{ - if (len) - { - uint32_t end_pc = start_pc + (len-1); + page_2->code_present_mask |= block->page_mask2; + if ((page_2->dirty_mask & block->page_mask2) && !page_in_evict_list(page_2)) + page_add_to_evict_list(page_2); - if (block->flags & CODEBLOCK_BYTE_MASK) - { - uint32_t start_pc_masked = start_pc & PAGE_MASK_MASK; - uint32_t end_pc_masked = end_pc & PAGE_MASK_MASK; + if (!pages[block->phys_2 >> 12].block_2) + mem_flush_write_page(block->phys_2, codegen_endpc); - if ((start_pc ^ block->pc) & ~0x3f) /*Starts in second page*/ - { - for (; start_pc_masked <= end_pc_masked; start_pc_masked++) - block->page_mask2 |= ((uint64_t)1 << start_pc_masked); - } - else if (((start_pc + (len-1)) ^ block->pc) & ~0x3f) /*Crosses both pages*/ - { - for (; start_pc_masked <= 63; start_pc_masked++) - block->page_mask |= ((uint64_t)1 << start_pc_masked); - for (start_pc_masked = 0; start_pc_masked <= end_pc_masked; start_pc_masked++) - block->page_mask2 |= ((uint64_t)1 << start_pc_masked); - } - else /*First page only*/ - { - for (; start_pc_masked <= end_pc_masked; start_pc_masked++) - block->page_mask |= ((uint64_t)1 << start_pc_masked); - } - } - else - { - uint32_t start_pc_shifted = start_pc >> PAGE_MASK_SHIFT; - uint32_t end_pc_shifted = end_pc >> PAGE_MASK_SHIFT; - start_pc_shifted &= PAGE_MASK_MASK; - end_pc_shifted &= PAGE_MASK_MASK; - - if ((start_pc ^ block->pc) & ~0xfff) /*Starts in second page*/ - { - for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) - block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); - } - else if (((start_pc + (len-1)) ^ block->pc) & ~0xfff) /*Crosses both pages*/ - { - for (; start_pc_shifted <= 63; start_pc_shifted++) - block->page_mask |= ((uint64_t)1 << start_pc_shifted); - for (start_pc_shifted = 0; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) - block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); - } - else /*First page only*/ - { - for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) - block->page_mask |= ((uint64_t)1 << start_pc_shifted); - } - } +#ifndef RELEASE_BUILD + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *) &codeblock[block->next_2]); + } +#endif + block->dirty_mask2 = &page_2->dirty_mask; + } else { + /*Second page not present. page_mask2 is most likely set only because + the recompiler didn't know how long the last instruction was, so + clear it*/ + block->page_mask2 = 0; } + } + + recomp_page = -1; +} + +void +codegen_block_end(void) +{ + codeblock_t *block = &codeblock[block_current]; + + codegen_block_generate_end_mask_mark(); + add_to_block_list(block); +} + +void +codegen_block_end_recompile(codeblock_t *block) +{ + codegen_timing_block_end(); + codegen_accumulate(ir_data, ACCREG_cycles, -codegen_block_cycles); + + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block_dirty_list_remove(block); + else + remove_from_block_list(block, block->pc); + block->next = block->prev = BLOCK_INVALID; + block->next_2 = block->prev_2 = BLOCK_INVALID; + codegen_block_generate_end_mask_recompile(); + add_to_block_list(block); + + if (!(block->flags & CODEBLOCK_HAS_FPU)) + block->flags &= ~CODEBLOCK_STATIC_TOP; + + codegen_accumulate_flush(ir_data); + codegen_ir_compile(ir_data, block); +} + +void +codegen_flush(void) +{ + return; +} + +void +codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len) +{ + if (len) { + uint32_t end_pc = start_pc + (len - 1); + + if (block->flags & CODEBLOCK_BYTE_MASK) { + uint32_t start_pc_masked = start_pc & PAGE_MASK_MASK; + uint32_t end_pc_masked = end_pc & PAGE_MASK_MASK; + + if ((start_pc ^ block->pc) & ~0x3f) /*Starts in second page*/ + { + for (; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask2 |= ((uint64_t) 1 << start_pc_masked); + } else if (((start_pc + (len - 1)) ^ block->pc) & ~0x3f) /*Crosses both pages*/ + { + for (; start_pc_masked <= 63; start_pc_masked++) + block->page_mask |= ((uint64_t) 1 << start_pc_masked); + for (start_pc_masked = 0; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask2 |= ((uint64_t) 1 << start_pc_masked); + } else /*First page only*/ + { + for (; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask |= ((uint64_t) 1 << start_pc_masked); + } + } else { + uint32_t start_pc_shifted = start_pc >> PAGE_MASK_SHIFT; + uint32_t end_pc_shifted = end_pc >> PAGE_MASK_SHIFT; + start_pc_shifted &= PAGE_MASK_MASK; + end_pc_shifted &= PAGE_MASK_MASK; + + if ((start_pc ^ block->pc) & ~0xfff) /*Starts in second page*/ + { + for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask2 |= ((uint64_t) 1 << start_pc_shifted); + } else if (((start_pc + (len - 1)) ^ block->pc) & ~0xfff) /*Crosses both pages*/ + { + for (; start_pc_shifted <= 63; start_pc_shifted++) + block->page_mask |= ((uint64_t) 1 << start_pc_shifted); + for (start_pc_shifted = 0; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask2 |= ((uint64_t) 1 << start_pc_shifted); + } else /*First page only*/ + { + for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask |= ((uint64_t) 1 << start_pc_shifted); + } + } + } } diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index 49a7adac5..bc38a3666 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -9,208 +9,186 @@ #include "codegen_ir.h" #include "codegen_reg.h" -extern int has_ea; +extern int has_ea; static ir_data_t ir_block; static int codegen_unroll_start, codegen_unroll_count; static int codegen_unroll_first_instruction; -ir_data_t *codegen_ir_init() +ir_data_t * +codegen_ir_init(void) { - ir_block.wr_pos = 0; + ir_block.wr_pos = 0; - codegen_unroll_count = 0; + codegen_unroll_count = 0; - return &ir_block; + return &ir_block; } -void codegen_ir_set_unroll(int count, int start, int first_instruction) +void +codegen_ir_set_unroll(int count, int start, int first_instruction) { - codegen_unroll_count = count; - codegen_unroll_start = start; - codegen_unroll_first_instruction = first_instruction; + codegen_unroll_count = count; + codegen_unroll_start = start; + codegen_unroll_first_instruction = first_instruction; } -static void duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) +static void +duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) { - uop_t *new_uop = uop_alloc(ir, uop->type); + uop_t *new_uop = uop_alloc(ir, uop->type); - if (!ir_reg_is_invalid(uop->src_reg_a)) - new_uop->src_reg_a = codegen_reg_read(uop->src_reg_a.reg); - if (!ir_reg_is_invalid(uop->src_reg_b)) - new_uop->src_reg_b = codegen_reg_read(uop->src_reg_b.reg); - if (!ir_reg_is_invalid(uop->src_reg_c)) - new_uop->src_reg_c = codegen_reg_read(uop->src_reg_c.reg); - if (!ir_reg_is_invalid(uop->dest_reg_a)) - new_uop->dest_reg_a = codegen_reg_write(uop->dest_reg_a.reg, ir->wr_pos-1); + if (!ir_reg_is_invalid(uop->src_reg_a)) + new_uop->src_reg_a = codegen_reg_read(uop->src_reg_a.reg); + if (!ir_reg_is_invalid(uop->src_reg_b)) + new_uop->src_reg_b = codegen_reg_read(uop->src_reg_b.reg); + if (!ir_reg_is_invalid(uop->src_reg_c)) + new_uop->src_reg_c = codegen_reg_read(uop->src_reg_c.reg); + if (!ir_reg_is_invalid(uop->dest_reg_a)) + new_uop->dest_reg_a = codegen_reg_write(uop->dest_reg_a.reg, ir->wr_pos - 1); - new_uop->type = uop->type; - new_uop->imm_data = uop->imm_data; - new_uop->p = uop->p; - new_uop->pc = uop->pc; + new_uop->type = uop->type; + new_uop->imm_data = uop->imm_data; + new_uop->p = uop->p; + new_uop->pc = uop->pc; - if (uop->jump_dest_uop != -1) - { - new_uop->jump_dest_uop = uop->jump_dest_uop + offset; + if (uop->jump_dest_uop != -1) { + new_uop->jump_dest_uop = uop->jump_dest_uop + offset; + } +} + +void +codegen_ir_compile(ir_data_t *ir, codeblock_t *block) +{ + int jump_target_at_end = -1; + int c; + + if (codegen_unroll_count) { + int unroll_count; + int unroll_end; + + codegen_set_loop_start(ir, codegen_unroll_first_instruction); + unroll_end = ir->wr_pos; + + for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) { + int offset = ir->wr_pos - codegen_unroll_start; + // pclog("Unroll from %i to %i, offset %i - iteration %i\n", codegen_unroll_start, ir->wr_pos, offset, unroll_count); + for (c = codegen_unroll_start; c < unroll_end; c++) { + // pclog(" Duplicate uop %i\n", c); + duplicate_uop(ir, &ir->uops[c], offset); + } } -} + } -void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) -{ - int jump_target_at_end = -1; - int c; + codegen_reg_mark_as_required(); + codegen_reg_process_dead_list(ir); + block_write_data = codeblock_allocator_get_ptr(block->head_mem_block); + block_pos = 0; + codegen_backend_prologue(block); - if (codegen_unroll_count) - { - int unroll_count; - int unroll_end; + for (c = 0; c < ir->wr_pos; c++) { + uop_t *uop = &ir->uops[c]; - codegen_set_loop_start(ir, codegen_unroll_first_instruction); - unroll_end = ir->wr_pos; + // pclog("uOP %i : %08x\n", c, uop->type); - for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) - { - int offset = ir->wr_pos - codegen_unroll_start; -// pclog("Unroll from %i to %i, offset %i - iteration %i\n", codegen_unroll_start, ir->wr_pos, offset, unroll_count); - for (c = codegen_unroll_start; c < unroll_end; c++) - { -// pclog(" Duplicate uop %i\n", c); - duplicate_uop(ir, &ir->uops[c], offset); - } - } + if (uop->type & UOP_TYPE_BARRIER) + codegen_reg_flush_invalidate(ir, block); + + if (uop->type & UOP_TYPE_JUMP_DEST) { + uop_t *uop_dest = uop; + + while (uop_dest->jump_list_next != -1) { + uop_dest = &ir->uops[uop_dest->jump_list_next]; + codegen_set_jump_dest(block, uop_dest->p); + } } - codegen_reg_mark_as_required(); - codegen_reg_process_dead_list(ir); - block_write_data = codeblock_allocator_get_ptr(block->head_mem_block); - block_pos = 0; - codegen_backend_prologue(block); - - for (c = 0; c < ir->wr_pos; c++) - { - uop_t *uop = &ir->uops[c]; - -// pclog("uOP %i : %08x\n", c, uop->type); - - if (uop->type & UOP_TYPE_BARRIER) - codegen_reg_flush_invalidate(ir, block); - - if (uop->type & UOP_TYPE_JUMP_DEST) - { - uop_t *uop_dest = uop; - - while (uop_dest->jump_list_next != -1) - { - uop_dest = &ir->uops[uop_dest->jump_list_next]; - codegen_set_jump_dest(block, uop_dest->p); - } - } - - if ((uop->type & UOP_MASK) == UOP_INVALID) - continue; + if ((uop->type & UOP_MASK) == UOP_INVALID) + continue; #ifdef CODEGEN_BACKEND_HAS_MOV_IMM - if ((uop->type & UOP_MASK) == (UOP_MOV_IMM & UOP_MASK) && reg_is_native_size(uop->dest_reg_a) && !codegen_reg_is_loaded(uop->dest_reg_a) && reg_version[IREG_GET_REG(uop->dest_reg_a.reg)][uop->dest_reg_a.version].refcount <= 0) - { - /*Special case for UOP_MOV_IMM - if destination not already in host register - and won't be used again then just store directly to memory*/ - codegen_reg_write_imm(block, uop->dest_reg_a, uop->imm_data); - } - else + if ((uop->type & UOP_MASK) == (UOP_MOV_IMM & UOP_MASK) && reg_is_native_size(uop->dest_reg_a) && !codegen_reg_is_loaded(uop->dest_reg_a) && reg_version[IREG_GET_REG(uop->dest_reg_a.reg)][uop->dest_reg_a.version].refcount <= 0) { + /*Special case for UOP_MOV_IMM - if destination not already in host register + and won't be used again then just store directly to memory*/ + codegen_reg_write_imm(block, uop->dest_reg_a, uop->imm_data); + } else #endif - if ((uop->type & UOP_MASK) == (UOP_MOV & UOP_MASK) && reg_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version].refcount <= 1 && - reg_is_native_size(uop->src_reg_a) && reg_is_native_size(uop->dest_reg_a)) - { - /*Special case for UOP_MOV - if source register won't be used again then - just rename it to dest register instead of moving*/ - codegen_reg_alloc_register(invalid_ir_reg, uop->src_reg_a, invalid_ir_reg, invalid_ir_reg); - uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); - codegen_reg_rename(block, uop->src_reg_a, uop->dest_reg_a); - if (uop->type & UOP_TYPE_ORDER_BARRIER) - codegen_reg_flush(ir, block); + if ((uop->type & UOP_MASK) == (UOP_MOV & UOP_MASK) && reg_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version].refcount <= 1 && reg_is_native_size(uop->src_reg_a) && reg_is_native_size(uop->dest_reg_a)) { + /*Special case for UOP_MOV - if source register won't be used again then + just rename it to dest register instead of moving*/ + codegen_reg_alloc_register(invalid_ir_reg, uop->src_reg_a, invalid_ir_reg, invalid_ir_reg); + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); + codegen_reg_rename(block, uop->src_reg_a, uop->dest_reg_a); + if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); + } else { + if (uop->type & UOP_TYPE_PARAMS_REGS) { + codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); + if (uop->src_reg_a.reg != IREG_INVALID) { + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); } - else - { - if (uop->type & UOP_TYPE_PARAMS_REGS) - { - codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); - if (uop->src_reg_a.reg != IREG_INVALID) - { - uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); - } - if (uop->src_reg_b.reg != IREG_INVALID) - { - uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); - } - if (uop->src_reg_c.reg != IREG_INVALID) - { - uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); - } - } + if (uop->src_reg_b.reg != IREG_INVALID) { + uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); + } + if (uop->src_reg_c.reg != IREG_INVALID) { + uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); + } + } - if (uop->type & UOP_TYPE_ORDER_BARRIER) - codegen_reg_flush(ir, block); + if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); - if (uop->type & UOP_TYPE_PARAMS_REGS) - { - if (uop->dest_reg_a.reg != IREG_INVALID) - { - uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); - } - } + if (uop->type & UOP_TYPE_PARAMS_REGS) { + if (uop->dest_reg_a.reg != IREG_INVALID) { + uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); + } + } #ifndef RELEASE_BUILD - if (!uop_handlers[uop->type & UOP_MASK]) - fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); + if (!uop_handlers[uop->type & UOP_MASK]) + fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); #endif - uop_handlers[uop->type & UOP_MASK](block, uop); - } - - if (uop->type & UOP_TYPE_JUMP) - { - if (uop->jump_dest_uop == ir->wr_pos) - { - if (jump_target_at_end == -1) - jump_target_at_end = c; - else - { - uop_t *uop_dest = &ir->uops[jump_target_at_end]; - - while (uop_dest->jump_list_next != -1) - uop_dest = &ir->uops[uop_dest->jump_list_next]; - - uop_dest->jump_list_next = c; - } - } - else - { - uop_t *uop_dest = &ir->uops[uop->jump_dest_uop]; - - while (uop_dest->jump_list_next != -1) - uop_dest = &ir->uops[uop_dest->jump_list_next]; - - uop_dest->jump_list_next = c; - ir->uops[uop->jump_dest_uop].type |= UOP_TYPE_JUMP_DEST; - } - } + uop_handlers[uop->type & UOP_MASK](block, uop); } - codegen_reg_flush_invalidate(ir, block); + if (uop->type & UOP_TYPE_JUMP) { + if (uop->jump_dest_uop == ir->wr_pos) { + if (jump_target_at_end == -1) + jump_target_at_end = c; + else { + uop_t *uop_dest = &ir->uops[jump_target_at_end]; - if (jump_target_at_end != -1) - { - uop_t *uop_dest = &ir->uops[jump_target_at_end]; - - while (1) - { - codegen_set_jump_dest(block, uop_dest->p); - if (uop_dest->jump_list_next == -1) - break; + while (uop_dest->jump_list_next != -1) uop_dest = &ir->uops[uop_dest->jump_list_next]; - } - } - codegen_backend_epilogue(block); - block_write_data = NULL; -// if (has_ea) -// fatal("IR compilation complete\n"); + uop_dest->jump_list_next = c; + } + } else { + uop_t *uop_dest = &ir->uops[uop->jump_dest_uop]; + + while (uop_dest->jump_list_next != -1) + uop_dest = &ir->uops[uop_dest->jump_list_next]; + + uop_dest->jump_list_next = c; + ir->uops[uop->jump_dest_uop].type |= UOP_TYPE_JUMP_DEST; + } + } + } + + codegen_reg_flush_invalidate(ir, block); + + if (jump_target_at_end != -1) { + uop_t *uop_dest = &ir->uops[jump_target_at_end]; + + while (1) { + codegen_set_jump_dest(block, uop_dest->p); + if (uop_dest->jump_list_next == -1) + break; + uop_dest = &ir->uops[uop_dest->jump_list_next]; + } + } + + codegen_backend_epilogue(block); + block_write_data = NULL; + // if (has_ea) + // fatal("IR compilation complete\n"); } diff --git a/src/codegen_new/codegen_ir.h b/src/codegen_new/codegen_ir.h index 60e75cfc9..ffae3eb75 100644 --- a/src/codegen_new/codegen_ir.h +++ b/src/codegen_new/codegen_ir.h @@ -1,6 +1,6 @@ #include "codegen_ir_defs.h" -ir_data_t *codegen_ir_init(); +ir_data_t *codegen_ir_init(void); void codegen_ir_set_unroll(int count, int start, int first_instruction); void codegen_ir_compile(ir_data_t *ir, codeblock_t *block); diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index 30bf44d98..26a1c3cb4 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -18,761 +18,793 @@ #define UOP_TYPE_ORDER_BARRIER (1 << 27) /*uOP uses source and dest registers*/ -#define UOP_TYPE_PARAMS_REGS (1 << 28) +#define UOP_TYPE_PARAMS_REGS (1 << 28) /*uOP uses pointer*/ #define UOP_TYPE_PARAMS_POINTER (1 << 29) /*uOP uses immediate data*/ -#define UOP_TYPE_PARAMS_IMM (1 << 30) +#define UOP_TYPE_PARAMS_IMM (1 << 30) /*uOP is a jump, with the destination uOP in uop->jump_dest_uop. The compiler must set jump_dest in the destination uOP to the address of the branch offset to be written when known.*/ -#define UOP_TYPE_JUMP (1 << 26) +#define UOP_TYPE_JUMP (1 << 26) /*uOP is the destination of a jump, and must set the destination offset of the jump at compile time.*/ #define UOP_TYPE_JUMP_DEST (1 << 25) - -#define UOP_LOAD_FUNC_ARG_0 (UOP_TYPE_PARAMS_REGS | 0x00) -#define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01) -#define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02) -#define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03) -#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08 | UOP_TYPE_BARRIER) -#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09 | UOP_TYPE_BARRIER) -#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER) -#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER) -#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_0 (UOP_TYPE_PARAMS_REGS | 0x00) +#define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01) +#define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02) +#define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03) +#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER) +#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) /*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p, check return value and exit block if non-zero*/ #define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) -#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) -#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) +#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) +#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) /*UOP_LOAD_SEG - load segment in src_reg_a to segment p via loadseg(), check return value and exit block if non-zero*/ -#define UOP_LOAD_SEG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x14 | UOP_TYPE_BARRIER) +#define UOP_LOAD_SEG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x14 | UOP_TYPE_BARRIER) /*UOP_JMP - jump to ptr*/ -#define UOP_JMP (UOP_TYPE_PARAMS_POINTER | 0x15 | UOP_TYPE_ORDER_BARRIER) +#define UOP_JMP (UOP_TYPE_PARAMS_POINTER | 0x15 | UOP_TYPE_ORDER_BARRIER) /*UOP_CALL_FUNC - call instruction handler at p, dest_reg = return value*/ -#define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) +#define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) /*UOP_JMP_DEST - jump to ptr*/ -#define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) -#define UOP_NOP_BARRIER (UOP_TYPE_BARRIER | 0x18) -#define UOP_STORE_P_IMM_16 (UOP_TYPE_PARAMS_IMM | 0x19) +#define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_NOP_BARRIER (UOP_TYPE_BARRIER | 0x18) +#define UOP_STORE_P_IMM_16 (UOP_TYPE_PARAMS_IMM | 0x19) #ifdef DEBUG_EXTRA /*UOP_LOG_INSTR - log non-recompiled instruction in imm_data*/ -#define UOP_LOG_INSTR (UOP_TYPE_PARAMS_IMM | 0x1f) +# define UOP_LOG_INSTR (UOP_TYPE_PARAMS_IMM | 0x1f) #endif /*UOP_MOV_PTR - dest_reg = p*/ -#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) +#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) /*UOP_MOV_IMM - dest_reg = imm_data*/ -#define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21) +#define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21) /*UOP_MOV - dest_reg = src_reg_a*/ -#define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) +#define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) /*UOP_MOVZX - dest_reg = zero_extend(src_reg_a)*/ -#define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23) +#define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23) /*UOP_MOVSX - dest_reg = sign_extend(src_reg_a)*/ -#define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24) +#define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24) /*UOP_MOV_DOUBLE_INT - dest_reg = (double)src_reg_a*/ -#define UOP_MOV_DOUBLE_INT (UOP_TYPE_PARAMS_REGS | 0x25) +#define UOP_MOV_DOUBLE_INT (UOP_TYPE_PARAMS_REGS | 0x25) /*UOP_MOV_INT_DOUBLE - dest_reg = (int)src_reg_a. New rounding control in src_reg_b, old rounding control in src_reg_c*/ -#define UOP_MOV_INT_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x26) +#define UOP_MOV_INT_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x26) /*UOP_MOV_INT_DOUBLE_64 - dest_reg = (int)src_reg_a. New rounding control in src_reg_b, old rounding control in src_reg_c*/ -#define UOP_MOV_INT_DOUBLE_64 (UOP_TYPE_PARAMS_REGS | 0x27) +#define UOP_MOV_INT_DOUBLE_64 (UOP_TYPE_PARAMS_REGS | 0x27) /*UOP_MOV_REG_PTR - dest_reg = *p*/ -#define UOP_MOV_REG_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x28) +#define UOP_MOV_REG_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x28) /*UOP_MOVZX_REG_PTR_8 - dest_reg = *(uint8_t *)p*/ -#define UOP_MOVZX_REG_PTR_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x29) +#define UOP_MOVZX_REG_PTR_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x29) /*UOP_MOVZX_REG_PTR_16 - dest_reg = *(uint16_t *)p*/ -#define UOP_MOVZX_REG_PTR_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x2a) +#define UOP_MOVZX_REG_PTR_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x2a) /*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/ -#define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) +#define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) /*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/ -#define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) +#define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) /*UOP_AND - dest_reg = src_reg_a & src_reg_b*/ -#define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) +#define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) /*UOP_AND_IMM - dest_reg = src_reg_a & immediate*/ -#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) +#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) /*UOP_ADD_LSHIFT - dest_reg = src_reg_a + (src_reg_b << imm_data) Intended for EA calcluations, imm_data must be between 0 and 3*/ -#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34) +#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34) /*UOP_OR - dest_reg = src_reg_a | src_reg_b*/ -#define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35) +#define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35) /*UOP_OR_IMM - dest_reg = src_reg_a | immediate*/ -#define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) +#define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) /*UOP_SUB - dest_reg = src_reg_a - src_reg_b*/ -#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) +#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) /*UOP_SUB_IMM - dest_reg = src_reg_a - immediate*/ -#define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) +#define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) /*UOP_XOR - dest_reg = src_reg_a ^ src_reg_b*/ -#define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) +#define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) /*UOP_XOR_IMM - dest_reg = src_reg_a ^ immediate*/ -#define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) +#define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) /*UOP_ANDN - dest_reg = ~src_reg_a & src_reg_b*/ -#define UOP_ANDN (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3b) +#define UOP_ANDN (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3b) /*UOP_MEM_LOAD_ABS - dest_reg = src_reg_a:[immediate]*/ -#define UOP_MEM_LOAD_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x40 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x40 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_REG - dest_reg = src_reg_a:[src_reg_b]*/ -#define UOP_MEM_LOAD_REG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x41 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_REG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x41 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_ABS - src_reg_a:[immediate] = src_reg_b*/ -#define UOP_MEM_STORE_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x42 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x42 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_REG - src_reg_a:[src_reg_b] = src_reg_c*/ -#define UOP_MEM_STORE_REG (UOP_TYPE_PARAMS_REGS | 0x43 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_REG (UOP_TYPE_PARAMS_REGS | 0x43 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_8 - byte src_reg_a:[src_reg_b] = imm_data*/ -#define UOP_MEM_STORE_IMM_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x44 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_IMM_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x44 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_16 - word src_reg_a:[src_reg_b] = imm_data*/ -#define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_32 - long src_reg_a:[src_reg_b] = imm_data*/ -#define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_SINGLE - dest_reg = (float)src_reg_a:[src_reg_b]*/ -#define UOP_MEM_LOAD_SINGLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x47 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_SINGLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x47 | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_IMM_JZ - if (src_reg_a == imm_data) then jump to ptr*/ -#define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) +#define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_DOUBLE - dest_reg = (double)src_reg_a:[src_reg_b]*/ -#define UOP_MEM_LOAD_DOUBLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x49 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_DOUBLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x49 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_SINGLE - src_reg_a:[src_reg_b] = src_reg_c*/ -#define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_DOUBLE - src_reg_a:[src_reg_b] = src_reg_c*/ -#define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_JB - if (src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JB (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4c | UOP_TYPE_ORDER_BARRIER) +#define UOP_CMP_JB (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4c | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_JNBE - if (src_reg_a > src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNBE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4d | UOP_TYPE_ORDER_BARRIER) +#define UOP_CMP_JNBE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4d | UOP_TYPE_ORDER_BARRIER) /*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/ -#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) +#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) /*UOP_SAR_IMM - dest_reg = src_reg_a >> immediate*/ -#define UOP_SAR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x51) +#define UOP_SAR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x51) /*UOP_SHL - dest_reg = src_reg_a << src_reg_b*/ -#define UOP_SHL (UOP_TYPE_PARAMS_REGS | 0x52) +#define UOP_SHL (UOP_TYPE_PARAMS_REGS | 0x52) /*UOP_SHL_IMM - dest_reg = src_reg_a << immediate*/ -#define UOP_SHL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x53) +#define UOP_SHL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x53) /*UOP_SHR - dest_reg = src_reg_a >> src_reg_b*/ -#define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54) +#define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54) /*UOP_SHR_IMM - dest_reg = src_reg_a >> immediate*/ -#define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55) +#define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55) /*UOP_ROL - dest_reg = src_reg_a rotate<< src_reg_b*/ -#define UOP_ROL (UOP_TYPE_PARAMS_REGS | 0x56) +#define UOP_ROL (UOP_TYPE_PARAMS_REGS | 0x56) /*UOP_ROL_IMM - dest_reg = src_reg_a rotate<< immediate*/ -#define UOP_ROL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x57) +#define UOP_ROL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x57) /*UOP_ROR - dest_reg = src_reg_a rotate>> src_reg_b*/ -#define UOP_ROR (UOP_TYPE_PARAMS_REGS | 0x58) +#define UOP_ROR (UOP_TYPE_PARAMS_REGS | 0x58) /*UOP_ROR_IMM - dest_reg = src_reg_a rotate>> immediate*/ -#define UOP_ROR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x59) +#define UOP_ROR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x59) /*UOP_CMP_IMM_JZ_DEST - if (src_reg_a == imm_data) then jump to ptr*/ -#define UOP_CMP_IMM_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x60 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_IMM_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x60 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_IMM_JNZ_DEST - if (src_reg_a != imm_data) then jump to ptr*/ -#define UOP_CMP_IMM_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x61 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_IMM_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x61 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JB_DEST - if (src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x62 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x62 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNB_DEST - if (src_reg_a >= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x63 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x63 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JO_DEST - if (src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x64 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x64 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNO_DEST - if (src_reg_a >= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x65 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x65 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JZ_DEST - if (src_reg_a == src_reg_b) then jump to ptr*/ -#define UOP_CMP_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x66 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x66 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNZ_DEST - if (src_reg_a != src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x67 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x67 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JL_DEST - if (signed)(src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x68 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x68 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNL_DEST - if (signed)(src_reg_a >= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x69 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x69 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JBE_DEST - if (src_reg_a <= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6a | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6a | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNBE_DEST - if (src_reg_a > src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6b | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6b | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JLE_DEST - if (signed)(src_reg_a <= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6c | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6c | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNLE_DEST - if (signed)(src_reg_a > src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6d | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) - +#define UOP_CMP_JNLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6d | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_TEST_JNS_DEST - if (src_reg_a positive) then jump to ptr*/ -#define UOP_TEST_JNS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x70 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_TEST_JNS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x70 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_TEST_JS_DEST - if (src_reg_a positive) then jump to ptr*/ -#define UOP_TEST_JS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_TEST_JS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_FP_ENTER - must be called before any FPU register accessed*/ -#define UOP_FP_ENTER (UOP_TYPE_PARAMS_IMM | 0x80 | UOP_TYPE_BARRIER) +#define UOP_FP_ENTER (UOP_TYPE_PARAMS_IMM | 0x80 | UOP_TYPE_BARRIER) /*UOP_FADD - (floating point) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_FADD (UOP_TYPE_PARAMS_REGS | 0x81) +#define UOP_FADD (UOP_TYPE_PARAMS_REGS | 0x81) /*UOP_FSUB - (floating point) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_FSUB (UOP_TYPE_PARAMS_REGS | 0x82) +#define UOP_FSUB (UOP_TYPE_PARAMS_REGS | 0x82) /*UOP_FMUL - (floating point) dest_reg = src_reg_a * src_reg_b*/ -#define UOP_FMUL (UOP_TYPE_PARAMS_REGS | 0x83) +#define UOP_FMUL (UOP_TYPE_PARAMS_REGS | 0x83) /*UOP_FDIV - (floating point) dest_reg = src_reg_a / src_reg_b*/ -#define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84) +#define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84) /*UOP_FCOM - dest_reg = flags from compare(src_reg_a, src_reg_b)*/ -#define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85) +#define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85) /*UOP_FABS - dest_reg = fabs(src_reg_a)*/ -#define UOP_FABS (UOP_TYPE_PARAMS_REGS | 0x86) +#define UOP_FABS (UOP_TYPE_PARAMS_REGS | 0x86) /*UOP_FCHS - dest_reg = fabs(src_reg_a)*/ -#define UOP_FCHS (UOP_TYPE_PARAMS_REGS | 0x87) +#define UOP_FCHS (UOP_TYPE_PARAMS_REGS | 0x87) /*UOP_FTST - dest_reg = flags from compare(src_reg_a, 0)*/ -#define UOP_FTST (UOP_TYPE_PARAMS_REGS | 0x88) +#define UOP_FTST (UOP_TYPE_PARAMS_REGS | 0x88) /*UOP_FSQRT - dest_reg = fsqrt(src_reg_a)*/ -#define UOP_FSQRT (UOP_TYPE_PARAMS_REGS | 0x89) +#define UOP_FSQRT (UOP_TYPE_PARAMS_REGS | 0x89) /*UOP_MMX_ENTER - must be called before any MMX registers accessed*/ -#define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER) +#define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER) /*UOP_PADDB - (packed byte) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDB (UOP_TYPE_PARAMS_REGS | 0x91) +#define UOP_PADDB (UOP_TYPE_PARAMS_REGS | 0x91) /*UOP_PADDW - (packed word) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDW (UOP_TYPE_PARAMS_REGS | 0x92) +#define UOP_PADDW (UOP_TYPE_PARAMS_REGS | 0x92) /*UOP_PADDD - (packed long) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDD (UOP_TYPE_PARAMS_REGS | 0x93) +#define UOP_PADDD (UOP_TYPE_PARAMS_REGS | 0x93) /*UOP_PADDSB - (packed byte with signed saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDSB (UOP_TYPE_PARAMS_REGS | 0x94) +#define UOP_PADDSB (UOP_TYPE_PARAMS_REGS | 0x94) /*UOP_PADDSW - (packed word with signed saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDSW (UOP_TYPE_PARAMS_REGS | 0x95) +#define UOP_PADDSW (UOP_TYPE_PARAMS_REGS | 0x95) /*UOP_PADDUSB - (packed byte with unsigned saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDUSB (UOP_TYPE_PARAMS_REGS | 0x96) +#define UOP_PADDUSB (UOP_TYPE_PARAMS_REGS | 0x96) /*UOP_PADDUSW - (packed word with unsigned saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDUSW (UOP_TYPE_PARAMS_REGS | 0x97) +#define UOP_PADDUSW (UOP_TYPE_PARAMS_REGS | 0x97) /*UOP_PSUBB - (packed byte) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBB (UOP_TYPE_PARAMS_REGS | 0x98) +#define UOP_PSUBB (UOP_TYPE_PARAMS_REGS | 0x98) /*UOP_PSUBW - (packed word) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBW (UOP_TYPE_PARAMS_REGS | 0x99) +#define UOP_PSUBW (UOP_TYPE_PARAMS_REGS | 0x99) /*UOP_PSUBD - (packed long) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBD (UOP_TYPE_PARAMS_REGS | 0x9a) +#define UOP_PSUBD (UOP_TYPE_PARAMS_REGS | 0x9a) /*UOP_PSUBSB - (packed byte with signed saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBSB (UOP_TYPE_PARAMS_REGS | 0x9b) +#define UOP_PSUBSB (UOP_TYPE_PARAMS_REGS | 0x9b) /*UOP_PSUBSW - (packed word with signed saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBSW (UOP_TYPE_PARAMS_REGS | 0x9c) +#define UOP_PSUBSW (UOP_TYPE_PARAMS_REGS | 0x9c) /*UOP_PSUBUSB - (packed byte with unsigned saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBUSB (UOP_TYPE_PARAMS_REGS | 0x9d) +#define UOP_PSUBUSB (UOP_TYPE_PARAMS_REGS | 0x9d) /*UOP_PSUBUSW - (packed word with unsigned saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBUSW (UOP_TYPE_PARAMS_REGS | 0x9e) +#define UOP_PSUBUSW (UOP_TYPE_PARAMS_REGS | 0x9e) /*UOP_PSLLW_IMM - (packed word) dest_reg = src_reg_a << immediate*/ -#define UOP_PSLLW_IMM (UOP_TYPE_PARAMS_REGS | 0x9f) +#define UOP_PSLLW_IMM (UOP_TYPE_PARAMS_REGS | 0x9f) /*UOP_PSLLD_IMM - (packed long) dest_reg = src_reg_a << immediate*/ -#define UOP_PSLLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa0) +#define UOP_PSLLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa0) /*UOP_PSLLQ_IMM - (packed quad) dest_reg = src_reg_a << immediate*/ -#define UOP_PSLLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa1) +#define UOP_PSLLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa1) /*UOP_PSRAW_IMM - (packed word) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRAW_IMM (UOP_TYPE_PARAMS_REGS | 0xa2) +#define UOP_PSRAW_IMM (UOP_TYPE_PARAMS_REGS | 0xa2) /*UOP_PSRAD_IMM - (packed long) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRAD_IMM (UOP_TYPE_PARAMS_REGS | 0xa3) +#define UOP_PSRAD_IMM (UOP_TYPE_PARAMS_REGS | 0xa3) /*UOP_PSRAQ_IMM - (packed quad) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRAQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa4) +#define UOP_PSRAQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa4) /*UOP_PSRLW_IMM - (packed word) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRLW_IMM (UOP_TYPE_PARAMS_REGS | 0xa5) +#define UOP_PSRLW_IMM (UOP_TYPE_PARAMS_REGS | 0xa5) /*UOP_PSRLD_IMM - (packed long) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa6) +#define UOP_PSRLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa6) /*UOP_PSRLQ_IMM - (packed quad) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa7) +#define UOP_PSRLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa7) /*UOP_PCMPEQB - (packed byte) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPEQB (UOP_TYPE_PARAMS_REGS | 0xa8) +#define UOP_PCMPEQB (UOP_TYPE_PARAMS_REGS | 0xa8) /*UOP_PCMPEQW - (packed word) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPEQW (UOP_TYPE_PARAMS_REGS | 0xa9) +#define UOP_PCMPEQW (UOP_TYPE_PARAMS_REGS | 0xa9) /*UOP_PCMPEQD - (packed long) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPEQD (UOP_TYPE_PARAMS_REGS | 0xaa) +#define UOP_PCMPEQD (UOP_TYPE_PARAMS_REGS | 0xaa) /*UOP_PCMPGTB - (packed signed byte) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPGTB (UOP_TYPE_PARAMS_REGS | 0xab) +#define UOP_PCMPGTB (UOP_TYPE_PARAMS_REGS | 0xab) /*UOP_PCMPGTW - (packed signed word) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPGTW (UOP_TYPE_PARAMS_REGS | 0xac) +#define UOP_PCMPGTW (UOP_TYPE_PARAMS_REGS | 0xac) /*UOP_PCMPGTD - (packed signed long) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPGTD (UOP_TYPE_PARAMS_REGS | 0xad) +#define UOP_PCMPGTD (UOP_TYPE_PARAMS_REGS | 0xad) /*UOP_PUNPCKLBW - (packed byte) dest_reg = interleave low src_reg_a/src_reg_b*/ -#define UOP_PUNPCKLBW (UOP_TYPE_PARAMS_REGS | 0xae) +#define UOP_PUNPCKLBW (UOP_TYPE_PARAMS_REGS | 0xae) /*UOP_PUNPCKLWD - (packed word) dest_reg = interleave low src_reg_a/src_reg_b*/ -#define UOP_PUNPCKLWD (UOP_TYPE_PARAMS_REGS | 0xaf) +#define UOP_PUNPCKLWD (UOP_TYPE_PARAMS_REGS | 0xaf) /*UOP_PUNPCKLDQ - (packed long) dest_reg = interleave low src_reg_a/src_reg_b*/ -#define UOP_PUNPCKLDQ (UOP_TYPE_PARAMS_REGS | 0xb0) +#define UOP_PUNPCKLDQ (UOP_TYPE_PARAMS_REGS | 0xb0) /*UOP_PUNPCKHBW - (packed byte) dest_reg = interleave high src_reg_a/src_reg_b*/ -#define UOP_PUNPCKHBW (UOP_TYPE_PARAMS_REGS | 0xb1) +#define UOP_PUNPCKHBW (UOP_TYPE_PARAMS_REGS | 0xb1) /*UOP_PUNPCKHWD - (packed word) dest_reg = interleave high src_reg_a/src_reg_b*/ -#define UOP_PUNPCKHWD (UOP_TYPE_PARAMS_REGS | 0xb2) +#define UOP_PUNPCKHWD (UOP_TYPE_PARAMS_REGS | 0xb2) /*UOP_PUNPCKHDQ - (packed long) dest_reg = interleave high src_reg_a/src_reg_b*/ -#define UOP_PUNPCKHDQ (UOP_TYPE_PARAMS_REGS | 0xb3) +#define UOP_PUNPCKHDQ (UOP_TYPE_PARAMS_REGS | 0xb3) /*UOP_PACKSSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with signed saturation*/ -#define UOP_PACKSSWB (UOP_TYPE_PARAMS_REGS | 0xb4) +#define UOP_PACKSSWB (UOP_TYPE_PARAMS_REGS | 0xb4) /*UOP_PACKSSDW - dest_reg = interleave src_reg_a/src_reg_b, converting longs to words with signed saturation*/ -#define UOP_PACKSSDW (UOP_TYPE_PARAMS_REGS | 0xb5) +#define UOP_PACKSSDW (UOP_TYPE_PARAMS_REGS | 0xb5) /*UOP_PACKUSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with unsigned saturation*/ -#define UOP_PACKUSWB (UOP_TYPE_PARAMS_REGS | 0xb6) +#define UOP_PACKUSWB (UOP_TYPE_PARAMS_REGS | 0xb6) /*UOP_PMULLW - (packed word) dest_reg = (src_reg_a * src_reg_b) & 0xffff*/ -#define UOP_PMULLW (UOP_TYPE_PARAMS_REGS | 0xb7) +#define UOP_PMULLW (UOP_TYPE_PARAMS_REGS | 0xb7) /*UOP_PMULHW - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/ -#define UOP_PMULHW (UOP_TYPE_PARAMS_REGS | 0xb8) +#define UOP_PMULHW (UOP_TYPE_PARAMS_REGS | 0xb8) /*UOP_PMADDWD - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/ -#define UOP_PMADDWD (UOP_TYPE_PARAMS_REGS | 0xb9) +#define UOP_PMADDWD (UOP_TYPE_PARAMS_REGS | 0xb9) /*UOP_PFADD - (packed float) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PFADD (UOP_TYPE_PARAMS_REGS | 0xba) +#define UOP_PFADD (UOP_TYPE_PARAMS_REGS | 0xba) /*UOP_PFSUB - (packed float) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PFSUB (UOP_TYPE_PARAMS_REGS | 0xbb) +#define UOP_PFSUB (UOP_TYPE_PARAMS_REGS | 0xbb) /*UOP_PFMUL - (packed float) dest_reg = src_reg_a * src_reg_b*/ -#define UOP_PFMUL (UOP_TYPE_PARAMS_REGS | 0xbc) +#define UOP_PFMUL (UOP_TYPE_PARAMS_REGS | 0xbc) /*UOP_PFMAX - (packed float) dest_reg = MAX(src_reg_a, src_reg_b)*/ -#define UOP_PFMAX (UOP_TYPE_PARAMS_REGS | 0xbd) +#define UOP_PFMAX (UOP_TYPE_PARAMS_REGS | 0xbd) /*UOP_PFMIN - (packed float) dest_reg = MIN(src_reg_a, src_reg_b)*/ -#define UOP_PFMIN (UOP_TYPE_PARAMS_REGS | 0xbe) +#define UOP_PFMIN (UOP_TYPE_PARAMS_REGS | 0xbe) /*UOP_PFCMPEQ - (packed float) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PFCMPEQ (UOP_TYPE_PARAMS_REGS | 0xbf) +#define UOP_PFCMPEQ (UOP_TYPE_PARAMS_REGS | 0xbf) /*UOP_PFCMPGE - (packed float) dest_reg = (src_reg_a >= src_reg_b) ? ~0 : 0*/ -#define UOP_PFCMPGE (UOP_TYPE_PARAMS_REGS | 0xc0) +#define UOP_PFCMPGE (UOP_TYPE_PARAMS_REGS | 0xc0) /*UOP_PFCMPGT - (packed float) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PFCMPGT (UOP_TYPE_PARAMS_REGS | 0xc1) +#define UOP_PFCMPGT (UOP_TYPE_PARAMS_REGS | 0xc1) /*UOP_PF2ID - (packed long)dest_reg = (packed float)src_reg_a*/ -#define UOP_PF2ID (UOP_TYPE_PARAMS_REGS | 0xc2) +#define UOP_PF2ID (UOP_TYPE_PARAMS_REGS | 0xc2) /*UOP_PI2FD - (packed float)dest_reg = (packed long)src_reg_a*/ -#define UOP_PI2FD (UOP_TYPE_PARAMS_REGS | 0xc3) +#define UOP_PI2FD (UOP_TYPE_PARAMS_REGS | 0xc3) /*UOP_PFRCP - (packed float) dest_reg[0] = dest_reg[1] = 1.0 / src_reg[0]*/ -#define UOP_PFRCP (UOP_TYPE_PARAMS_REGS | 0xc4) +#define UOP_PFRCP (UOP_TYPE_PARAMS_REGS | 0xc4) /*UOP_PFRSQRT - (packed float) dest_reg[0] = dest_reg[1] = 1.0 / sqrt(src_reg[0])*/ -#define UOP_PFRSQRT (UOP_TYPE_PARAMS_REGS | 0xc5) +#define UOP_PFRSQRT (UOP_TYPE_PARAMS_REGS | 0xc5) -#define UOP_MAX 0xc6 +#define UOP_MAX 0xc6 #define UOP_INVALID 0xff -#define UOP_MASK 0xffff +#define UOP_MASK 0xffff -typedef struct uop_t -{ - uint32_t type; - ir_reg_t dest_reg_a; - ir_reg_t src_reg_a; - ir_reg_t src_reg_b; - ir_reg_t src_reg_c; - uint32_t imm_data; - void *p; - ir_host_reg_t dest_reg_a_real; - ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; - int jump_dest_uop; - int jump_list_next; - void *jump_dest; - uint32_t pc; +typedef struct uop_t { + uint32_t type; + ir_reg_t dest_reg_a; + ir_reg_t src_reg_a; + ir_reg_t src_reg_b; + ir_reg_t src_reg_c; + uint32_t imm_data; + void *p; + ir_host_reg_t dest_reg_a_real; + ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; + int jump_dest_uop; + int jump_list_next; + void *jump_dest; + uint32_t pc; } uop_t; #define UOP_NR_MAX 4096 -typedef struct ir_data_t -{ - uop_t uops[UOP_NR_MAX]; - int wr_pos; - struct codeblock_t *block; +typedef struct ir_data_t { + uop_t uops[UOP_NR_MAX]; + int wr_pos; + struct codeblock_t *block; } ir_data_t; -static inline uop_t *uop_alloc(ir_data_t *ir, uint32_t uop_type) +static inline uop_t * +uop_alloc(ir_data_t *ir, uint32_t uop_type) { - uop_t *uop; + uop_t *uop; - if (ir->wr_pos >= UOP_NR_MAX) - fatal("Exceeded uOP max\n"); + if (ir->wr_pos >= UOP_NR_MAX) + fatal("Exceeded uOP max\n"); - uop = &ir->uops[ir->wr_pos++]; + uop = &ir->uops[ir->wr_pos++]; - uop->dest_reg_a = invalid_ir_reg; - uop->src_reg_a = invalid_ir_reg; - uop->src_reg_b = invalid_ir_reg; - uop->src_reg_c = invalid_ir_reg; + uop->dest_reg_a = invalid_ir_reg; + uop->src_reg_a = invalid_ir_reg; + uop->src_reg_b = invalid_ir_reg; + uop->src_reg_c = invalid_ir_reg; - uop->pc = cpu_state.oldpc; + uop->pc = cpu_state.oldpc; - uop->jump_dest_uop = -1; - uop->jump_list_next = -1; + uop->jump_dest_uop = -1; + uop->jump_list_next = -1; - if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER)) - codegen_reg_mark_as_required(); + if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER)) + codegen_reg_mark_as_required(); - return uop; + return uop; } -static inline void uop_set_jump_dest(ir_data_t *ir, int jump_uop) +static inline void +uop_set_jump_dest(ir_data_t *ir, int jump_uop) { - uop_t *uop = &ir->uops[jump_uop]; + uop_t *uop = &ir->uops[jump_uop]; - uop->jump_dest_uop = ir->wr_pos; + uop->jump_dest_uop = ir->wr_pos; } -static inline int uop_gen(uint32_t uop_type, ir_data_t *ir) +static inline int +uop_gen(uint32_t uop_type, ir_data_t *ir) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; + uop->type = uop_type; - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline int uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) +static inline int +uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline void uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) +static inline void +uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); } -static inline int uop_gen_reg_src1_imm(uint32_t uop_type, ir_data_t *ir, int src_reg, uint32_t imm) +static inline int +uop_gen_reg_src1_imm(uint32_t uop_type, ir_data_t *ir, int src_reg, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg); + uop->imm_data = imm; - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline void uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, uint32_t imm) +static inline void +uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->imm_data = imm; + uop->type = uop_type; + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->imm_data = imm; } -static inline void uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int dest_reg, void *p) +static inline void +uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int dest_reg, void *p) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->p = p; + uop->type = uop_type; + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->p = p; } -static inline void uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg) +static inline void +uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } -static inline void uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, uint32_t imm) +static inline void +uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->imm_data = imm; } -static inline void uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b) +static inline void +uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } -static inline void uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, uint32_t imm) +static inline void +uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->imm_data = imm; } -static inline void uop_gen_reg_dst_src3(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, int src_reg_c) +static inline void +uop_gen_reg_dst_src3(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, int src_reg_c) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->src_reg_c = codegen_reg_read(src_reg_c); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->src_reg_c = codegen_reg_read(src_reg_c); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } -static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg, uint32_t imm) +static inline void +uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->imm_data = imm; } -static inline int uop_gen_reg_src2(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b) +static inline int +uop_gen_reg_src2(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline void uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, uint32_t imm) +static inline void +uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->imm_data = imm; } -static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c) +static inline void +uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->src_reg_c = codegen_reg_read(src_reg_c); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->src_reg_c = codegen_reg_read(src_reg_c); } -static inline void uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c, uint32_t imm) +static inline void +uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->src_reg_c = codegen_reg_read(src_reg_c); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->src_reg_c = codegen_reg_read(src_reg_c); + uop->imm_data = imm; } -static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) +static inline void +uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->imm_data = imm; + uop->type = uop_type; + uop->imm_data = imm; } -static inline void uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p) +static inline void +uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->p = p; + uop->type = uop_type; + uop->p = p; } -static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p, uint32_t imm) +static inline void +uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->p = p; - uop->imm_data = imm; + uop->type = uop_type; + uop->p = p; + uop->imm_data = imm; } -static inline void uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p) +static inline void +uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->p = p; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->p = p; } -static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm) +static inline void +uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->p = p; - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->p = p; + uop->imm_data = imm; } -static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, void *p) +static inline void +uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, void *p) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->p = p; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->p = p; } -#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) +#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) -#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) +#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) -#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) +#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) #define uop_ADD_LSHIFT(ir, dst_reg, src_reg_a, src_reg_b, shift) uop_gen_reg_dst_src2_imm(UOP_ADD_LSHIFT, ir, dst_reg, src_reg_a, src_reg_b, shift) -#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) -#define uop_ANDN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ANDN, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) -#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) +#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) +#define uop_ANDN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ANDN, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) +#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg) -#define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SHL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHL, ir, dst_reg, src_reg, shift_reg) -#define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm) -#define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg) -#define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm) -#define uop_ROL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROL, ir, dst_reg, src_reg, shift_reg) -#define uop_ROL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROL_IMM, ir, dst_reg, src_reg, imm) -#define uop_ROR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROR, ir, dst_reg, src_reg, shift_reg) -#define uop_ROR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg) +#define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SHL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHL, ir, dst_reg, src_reg, shift_reg) +#define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm) +#define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg) +#define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm) +#define uop_ROL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROL, ir, dst_reg, src_reg, shift_reg) +#define uop_ROL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROL_IMM, ir, dst_reg, src_reg, imm) +#define uop_ROR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROR, ir, dst_reg, src_reg, shift_reg) +#define uop_ROR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROR_IMM, ir, dst_reg, src_reg, imm) -#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) -#define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p) -#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) +#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) +#define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p) +#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) -#define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) +#define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) -#define uop_CMP_IMM_JNZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JNZ_DEST, ir, src_reg, imm) -#define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm) +#define uop_CMP_IMM_JNZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JNZ_DEST, ir, src_reg, imm) +#define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm) -#define uop_CMP_JB(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JB, ir, src_reg_a, src_reg_b, p) -#define uop_CMP_JNBE(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JNBE, ir, src_reg_a, src_reg_b, p) +#define uop_CMP_JB(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JB, ir, src_reg_a, src_reg_b, p) +#define uop_CMP_JNBE(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JNBE, ir, src_reg_a, src_reg_b, p) -#define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNBE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNLE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNO_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNZ_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JB_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JBE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JL_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JLE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JO_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JZ_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNBE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNLE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNO_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNZ_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JB_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JBE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JL_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JLE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JO_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JZ_DEST, ir, src_reg_a, src_reg_b) -#define uop_FADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FCOM(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FCOM, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FDIV(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FDIV, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FCOM(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FCOM, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FDIV(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FDIV, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FABS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FABS, ir, dst_reg, src_reg) -#define uop_FCHS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FCHS, ir, dst_reg, src_reg) -#define uop_FSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FSQRT, ir, dst_reg, src_reg) -#define uop_FTST(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FTST, ir, dst_reg, src_reg) +#define uop_FABS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FABS, ir, dst_reg, src_reg) +#define uop_FCHS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FCHS, ir, dst_reg, src_reg) +#define uop_FSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FSQRT, ir, dst_reg, src_reg) +#define uop_FTST(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FTST, ir, dst_reg, src_reg) -#define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; codegen_mmx_entered = 0; } while (0) -#define uop_MMX_ENTER(ir) do { if (!codegen_mmx_entered) uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); codegen_mmx_entered = 1; codegen_fpu_entered = 0; } while (0) +#define uop_FP_ENTER(ir) \ + do { \ + if (!codegen_fpu_entered) \ + uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); \ + codegen_fpu_entered = 1; \ + codegen_mmx_entered = 0; \ + } while (0) +#define uop_MMX_ENTER(ir) \ + do { \ + if (!codegen_mmx_entered) \ + uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); \ + codegen_mmx_entered = 1; \ + codegen_fpu_entered = 0; \ + } while (0) -#define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) -#define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) +#define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) +#define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) -#define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) +#define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) -#define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) -#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0) -#define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset) -#define uop_MEM_LOAD_SINGLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_SINGLE, ir, dst_reg, seg_reg, addr_reg, 0) -#define uop_MEM_LOAD_DOUBLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_DOUBLE, ir, dst_reg, seg_reg, addr_reg, 0) -#define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm) -#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) +#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset) +#define uop_MEM_LOAD_SINGLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_SINGLE, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_LOAD_DOUBLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_DOUBLE, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm) +#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0) #define uop_MEM_STORE_REG_OFFSET(ir, seg_reg, addr_reg, offset, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, offset) -#define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm) -#define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm) -#define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm) -#define uop_MEM_STORE_SINGLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_SINGLE, ir, seg_reg, addr_reg, src_reg, 0) -#define uop_MEM_STORE_DOUBLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_DOUBLE, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm) +#define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm) +#define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm) +#define uop_MEM_STORE_SINGLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_SINGLE, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_STORE_DOUBLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_DOUBLE, ir, seg_reg, addr_reg, src_reg, 0) -#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) -#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) -#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) -#define uop_MOV_REG_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_REG_PTR, ir, reg, p) -#define uop_MOVZX_REG_PTR_8(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_8, ir, reg, p) -#define uop_MOVZX_REG_PTR_16(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_16, ir, reg, p) -#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) -#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) -#define uop_MOV_DOUBLE_INT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV_DOUBLE_INT, ir, dst_reg, src_reg) -#define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg/*, nrc, orc*/) uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg/*, nrc, orc*/) -#define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) +#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) +#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) +#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) +#define uop_MOV_REG_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_REG_PTR, ir, reg, p) +#define uop_MOVZX_REG_PTR_8(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_8, ir, reg, p) +#define uop_MOVZX_REG_PTR_16(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_16, ir, reg, p) +#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) +#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) +#define uop_MOV_DOUBLE_INT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV_DOUBLE_INT, ir, dst_reg, src_reg) +#define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg /*, nrc, orc*/) uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg /*, nrc, orc*/) +#define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) -#define uop_NOP_BARRIER(ir) uop_gen(UOP_NOP_BARRIER, ir) +#define uop_NOP_BARRIER(ir) uop_gen(UOP_NOP_BARRIER, ir) -#define uop_PACKSSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSWB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PACKSSDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSDW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PACKUSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKUSWB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PACKSSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSWB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PACKSSDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSDW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PACKUSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKUSWB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPEQB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPEQW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPEQD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPGTB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPGTW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPGTD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPEQB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPEQW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPEQD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPGTB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPGTW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPGTD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PF2ID(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PF2ID, ir, dst_reg, src_reg) -#define uop_PFADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFCMPEQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPEQ, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFCMPGE(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGE, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFCMPGT(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGT, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFMAX(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMAX, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFMIN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMIN, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMUL, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFRCP(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRCP, ir, dst_reg, src_reg) -#define uop_PFRSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRSQRT, ir, dst_reg, src_reg) -#define uop_PFSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFSUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PI2FD(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PI2FD, ir, dst_reg, src_reg) +#define uop_PF2ID(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PF2ID, ir, dst_reg, src_reg) +#define uop_PFADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFCMPEQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPEQ, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFCMPGE(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGE, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFCMPGT(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGT, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMAX(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMAX, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMIN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMIN, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMUL, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFRCP(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRCP, ir, dst_reg, src_reg) +#define uop_PFRSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRSQRT, ir, dst_reg, src_reg) +#define uop_PFSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFSUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PI2FD(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PI2FD, ir, dst_reg, src_reg) -#define uop_PMADDWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMADDWD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PMULHW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULHW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PMULLW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULLW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMADDWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMADDWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMULHW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULHW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMULLW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULLW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRAW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAW_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRAD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAD_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRAQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAQ_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLW_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLD_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLQ_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSUBB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKHBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHBW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKHWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHWD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKHDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHDQ, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKLBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLBW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKLWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLWD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKLDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLDQ, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKHBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKHWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKHDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHDQ, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKLBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKLWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKLDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLDQ, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) -#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) -#define uop_STORE_PTR_IMM_16(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_16, ir, p, imm) +#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) +#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) +#define uop_STORE_PTR_IMM_16(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_16, ir, p, imm) -#define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) -#define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) +#define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) +#define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) #ifdef DEBUG_EXTRA -#define uop_LOG_INSTR(ir, imm) uop_gen_imm(UOP_LOG_INSTR, ir, imm) +# define uop_LOG_INSTR(ir, imm) uop_gen_imm(UOP_LOG_INSTR, ir, imm) #endif void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index 1e7183fff..3fadd4a13 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -26,8 +26,8 @@ #include "codegen_ops_shift.h" #include "codegen_ops_stack.h" -RecompOpFn recomp_opcodes[512] = -{ +RecompOpFn recomp_opcodes[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, @@ -71,11 +71,11 @@ RecompOpFn recomp_opcodes[512] = /*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, ropJMP_far_32, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_32, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, ropFF_32 + // clang-format on }; - -RecompOpFn recomp_opcodes_0f[512] = -{ +RecompOpFn recomp_opcodes_0f[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -141,10 +141,11 @@ RecompOpFn recomp_opcodes_0f[512] = /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, #endif + // clang-format on }; -RecompOpFn recomp_opcodes_3DNOW[256] = -{ +RecompOpFn recomp_opcodes_3DNOW[256] = { +// clang-format off #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 0 #else @@ -169,10 +170,11 @@ RecompOpFn recomp_opcodes_3DNOW[256] = /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, #endif + // clang-format on }; -RecompOpFn recomp_opcodes_d8[512] = -{ +RecompOpFn recomp_opcodes_d8[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, @@ -216,10 +218,11 @@ RecompOpFn recomp_opcodes_d8[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, /*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, + // clang-format on }; -RecompOpFn recomp_opcodes_d9[512] = -{ +RecompOpFn recomp_opcodes_d9[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -263,10 +266,11 @@ RecompOpFn recomp_opcodes_d9[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ ropFCHS, ropFABS, NULL, NULL, ropFTST, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSQRT, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_da[512] = -{ +RecompOpFn recomp_opcodes_da[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, @@ -310,10 +314,11 @@ RecompOpFn recomp_opcodes_da[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFUCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_db[512] = -{ +RecompOpFn recomp_opcodes_db[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -357,10 +362,11 @@ RecompOpFn recomp_opcodes_db[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_dc[512] = -{ +RecompOpFn recomp_opcodes_dc[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, @@ -404,10 +410,11 @@ RecompOpFn recomp_opcodes_dc[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, + // clang-format on }; -RecompOpFn recomp_opcodes_dd[512] = -{ +RecompOpFn recomp_opcodes_dd[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -451,10 +458,11 @@ RecompOpFn recomp_opcodes_dd[512] = /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -RecompOpFn recomp_opcodes_de[512] = -{ +RecompOpFn recomp_opcodes_de[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, @@ -498,10 +506,11 @@ RecompOpFn recomp_opcodes_de[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, /*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, + // clang-format on }; -RecompOpFn recomp_opcodes_df[512] = -{ +RecompOpFn recomp_opcodes_df[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -545,4 +554,5 @@ RecompOpFn recomp_opcodes_df[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; diff --git a/src/codegen_new/codegen_ops.h b/src/codegen_new/codegen_ops.h index 361479b6d..9cef07e15 100644 --- a/src/codegen_new/codegen_ops.h +++ b/src/codegen_new/codegen_ops.h @@ -29,21 +29,21 @@ extern RecompOpFn recomp_opcodes_REPNE[512];*/ #define REG_EBP 5 #define REG_ESI 6 #define REG_EDI 7 -#define REG_AX 0 -#define REG_CX 1 -#define REG_DX 2 -#define REG_BX 3 -#define REG_SP 4 -#define REG_BP 5 -#define REG_SI 6 -#define REG_DI 7 -#define REG_AL 0 -#define REG_AH 4 -#define REG_CL 1 -#define REG_CH 5 -#define REG_DL 2 -#define REG_DH 6 -#define REG_BL 3 -#define REG_BH 7 +#define REG_AX 0 +#define REG_CX 1 +#define REG_DX 2 +#define REG_BX 3 +#define REG_SP 4 +#define REG_BP 5 +#define REG_SI 6 +#define REG_DI 7 +#define REG_AL 0 +#define REG_AH 4 +#define REG_CL 1 +#define REG_CH 5 +#define REG_DL 2 +#define REG_DH 6 +#define REG_BL 3 +#define REG_BH 7 #endif diff --git a/src/codegen_new/codegen_ops_3dnow.c b/src/codegen_new/codegen_ops_3dnow.c index 2c4ecc353..ff0c136e2 100644 --- a/src/codegen_new/codegen_ops_3dnow.c +++ b/src/codegen_new/codegen_ops_3dnow.c @@ -13,199 +13,184 @@ #include "codegen_ops_3dnow.h" #include "codegen_ops_helpers.h" -#define ropParith(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - codegen_mark_code_present(block, cs+op_pc+1, 1); \ - return op_pc + 2; \ -} +#define ropParith(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + codegen_mark_code_present(block, cs + op_pc + 1, 1); \ + return op_pc + 2; \ + } ropParith(PFADD) -ropParith(PFCMPEQ) -ropParith(PFCMPGE) -ropParith(PFCMPGT) -ropParith(PFMAX) -ropParith(PFMIN) -ropParith(PFMUL) -ropParith(PFSUB) + ropParith(PFCMPEQ) + ropParith(PFCMPGE) + ropParith(PFCMPGT) + ropParith(PFMAX) + ropParith(PFMIN) + ropParith(PFMUL) + ropParith(PFSUB) -uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PF2ID(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PF2ID(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PF2ID(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PF2ID(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PFSUB(ir, IREG_MM(dest_reg), IREG_MM(src_reg), IREG_MM(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PFSUB(ir, IREG_MM(dest_reg), IREG_MM(src_reg), IREG_MM(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PFSUB(ir, IREG_MM(dest_reg), IREG_temp0_Q, IREG_MM(dest_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFSUB(ir, IREG_MM(dest_reg), IREG_temp0_Q, IREG_MM(dest_reg)); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PI2FD(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PI2FD(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PI2FD(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PI2FD(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PFRCP(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PFRCP(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PFRCP(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFRCP(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MMX_ENTER(ir); + uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } diff --git a/src/codegen_new/codegen_ops_arith.c b/src/codegen_new/codegen_ops_arith.c index 66715730d..5325b282b 100644 --- a/src/codegen_new/codegen_ops_arith.c +++ b/src/codegen_new/codegen_ops_arith.c @@ -12,2509 +12,2378 @@ #include "codegen_ops_arith.h" #include "codegen_ops_helpers.h" -static inline void get_cf(ir_data_t *ir, int dest_reg) +static inline void +get_cf(ir_data_t *ir, int dest_reg) { - uop_CALL_FUNC_RESULT(ir, dest_reg, CF_SET); + uop_CALL_FUNC_RESULT(ir, dest_reg, CF_SET); } -uint32_t ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_ADD(ir, IREG_AL, IREG_AL, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_ADD(ir, IREG_AL, IREG_AL, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_ADD(ir, IREG_AX, IREG_AX, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_ADD(ir, IREG_AX, IREG_AX, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + fetchdat = fastreadl(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; +} +uint32_t +ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } + + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); + uop_ADD(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } + + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); + uop_ADD(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } + + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); + uop_ADD(ir, IREG_temp2, IREG_temp2, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp2); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t +ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} +uint32_t +ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; +} +uint32_t +ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { fetchdat = fastreadl(cs + op_pc); - - get_cf(ir, IREG_temp0); - uop_MOV(ir, IREG_flags_op1, IREG_EAX); uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + codegen_mark_code_present(block, cs + op_pc, 4); + } - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + codegen_flags_changed = 1; + return op_pc + 4; } -uint32_t ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); - uop_ADD(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); - uop_ADD(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } - - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); - uop_ADD(ir, IREG_temp2, IREG_temp2, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp2); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_AL, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_AX, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV(ir, IREG_flags_op1, IREG_EAX); + fetchdat = fastreadl(cs + op_pc); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - codegen_mark_code_present(block, cs+op_pc, 4); - } + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } -uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_temp0_B, IREG_8(src_reg)); + } + + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + } + + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_16(src_reg)); + } + + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_32(src_reg)); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t +ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_SUB(ir, IREG_AL, IREG_AL, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} +uint32_t +ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_SUB(ir, IREG_AX, IREG_AX, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; +} +uint32_t +ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; +} +uint32_t +ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } + + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); + uop_SUB(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); + uop_SUB(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); + uop_SUB(ir, IREG_temp2, IREG_temp2, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp2); + } - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_AL, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_AX, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { fetchdat = fastreadl(cs + op_pc); - - uop_MOV(ir, IREG_flags_op1, IREG_EAX); - uop_SUB_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; -} -uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); - } - - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_temp0_B, IREG_8(src_reg)); - } - - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_16(src_reg)); - } - - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_32(src_reg)); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint8_t imm_data = fastreadb(cs + op_pc); - - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_SUB(ir, IREG_AL, IREG_AL, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; -} -uint32_t ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint16_t imm_data = fastreadw(cs + op_pc); - - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_SUB(ir, IREG_AX, IREG_AX, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; -} -uint32_t ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - fetchdat = fastreadl(cs + op_pc); - - get_cf(ir, IREG_temp0); - uop_MOV(ir, IREG_flags_op1, IREG_EAX); + codegen_mark_code_present(block, cs + op_pc, 4); uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + } - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; } -uint32_t ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); - uop_SUB(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); - uop_SUB(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } - - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int skip_immediate = 0; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint8_t imm = fastreadb(cs + op_pc + 1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); - uop_SUB(ir, IREG_temp2, IREG_temp2, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp2); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp0_B, cs + op_pc + 1); } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint8_t imm_data = fastreadb(cs + op_pc); - - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; -} -uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint16_t imm_data = fastreadw(cs + op_pc); - - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; -} -uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uop_MOV(ir, IREG_flags_op1, IREG_EAX); - - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); - - codegen_flags_changed = 1; - return op_pc + 4; -} -uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; + + default: + return 0; } + } else { + x86seg *target_seg; + uint8_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); else - { - x86seg *target_seg; + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; - codegen_flags_changed = 1; - return op_pc + 1; + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_ADD(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; + + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_temp0_B, imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int skip_immediate = 0; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint16_t imm = fastreadw(cs + op_pc + 1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp0_W, cs + op_pc + 1); } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; } + } else { + x86seg *target_seg; + uint16_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); else - { - x86seg *target_seg; + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadw(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp2_W, cs + op_pc + 1); + } - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x28: /*SUB*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_temp2_W); + } else { + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + } + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; } + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs + op_pc + 1, 2); + return op_pc + 3; } -uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int skip_immediate = 0; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint32_t imm = fastreadl(cs + op_pc + 1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc + 1); } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; } + } else { + x86seg *target_seg; + uint32_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); else - { - x86seg *target_seg; + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadl(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp2, cs + op_pc + 1); + } - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); uop_MOV(ir, IREG_flags_res, IREG_temp1); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int skip_immediate = 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint8_t imm = fastreadb(cs + op_pc + 1); + break; + case 0x08: /*OR*/ if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp0_B, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - else - uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - else - uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - else - uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint8_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadb(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_ADD(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - break; - - case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_temp0_B, imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - if (!skip_immediate) - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; -} -uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int skip_immediate = 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint16_t imm = fastreadw(cs + op_pc + 1); + uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp3); if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp0_W, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - else - uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - else - uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - else - uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint16_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadw(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp3); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp2_W, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); - else - uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); - else - uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x28: /*SUB*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); - else - uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_temp2_W); - } - else - { - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); - } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - if (!skip_immediate) - codegen_mark_code_present(block, cs+op_pc+1, 2); - return op_pc + 3; -} -uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int skip_immediate = 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint32_t imm = fastreadl(cs + op_pc + 1); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp3); if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - else - uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - else - uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - else - uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint32_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadl(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp3); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp2, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp2); - else - uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp3); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp3); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_temp0, IREG_temp0, IREG_temp2); - else - uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x28: /*SUB*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_temp2); - else - uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_temp2); - } - else - { - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - if (!skip_immediate) - codegen_mark_code_present(block, cs+op_pc+1, 4); - return op_pc + 5; -} - -uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint16_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; -} -uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint32_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_temp0, IREG_temp0, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x28: /*SUB*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + else + uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; - - default: - return 0; + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_temp2); + } else { + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); } - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + default: + return 0; + } + } + + codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs + op_pc + 1, 4); + return op_pc + 5; } -static void rebuild_c(ir_data_t *ir) +uint32_t +rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int needs_rebuild = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint16_t imm = (int16_t) (int8_t) fastreadb(cs + op_pc + 1); - if (codegen_flags_changed) - { - switch (cpu_state.flags_op) - { - case FLAGS_INC8: case FLAGS_INC16: case FLAGS_INC32: - case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: - needs_rebuild = 0; - break; - } - } + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - if (needs_rebuild) - { - uop_CALL_FUNC(ir, flags_rebuild_c); + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; } + } else { + x86seg *target_seg; + uint16_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); + imm = (int16_t) (int8_t) fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; +} +uint32_t +rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint32_t imm = (int32_t) (int8_t) fastreadb(cs + op_pc + 1); + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + } else { + x86seg *target_seg; + uint32_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); + imm = (int32_t) (int8_t) fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static void +rebuild_c(ir_data_t *ir) { - rebuild_c(ir); + int needs_rebuild = 1; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); - uop_ADD_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); - uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + if (codegen_flags_changed) { + switch (cpu_state.flags_op) { + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } + + if (needs_rebuild) { + uop_CALL_FUNC(ir, flags_rebuild_c); + } +} + +uint32_t +ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_ADD_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + codegen_flags_changed = 1; + + return op_pc; +} +uint32_t +ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_ADD_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + codegen_flags_changed = 1; + + return op_pc; +} + +uint32_t +ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_SUB_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + codegen_flags_changed = 1; + + return op_pc; +} +uint32_t +ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_SUB_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + codegen_flags_changed = 1; + + return op_pc; +} + +uint32_t +ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + codegen_mark_code_present(block, cs + op_pc, 1); + rebuild_c(ir); + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op1, IREG_8(fetchdat & 7)); + if (fetchdat & 0x38) { + uop_SUB_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } else { + uop_ADD_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); + } + uop_MOVZX(ir, IREG_flags_res, IREG_8(fetchdat & 7)); uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); - codegen_flags_changed = 1; + } else { + x86seg *target_seg; - return op_pc; -} -uint32_t ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - rebuild_c(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); - uop_ADD_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); - uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); - codegen_flags_changed = 1; - - return op_pc; -} - -uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - rebuild_c(ir); - - uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); - uop_SUB_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); - uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); - codegen_flags_changed = 1; - - return op_pc; -} -uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - rebuild_c(ir); - - uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); - uop_SUB_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); - uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); - codegen_flags_changed = 1; - - return op_pc; -} - -uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - codegen_mark_code_present(block, cs+op_pc, 1); - rebuild_c(ir); - - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op1, IREG_8(fetchdat & 7)); - if (fetchdat & 0x38) - { - uop_SUB_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); - } - else - { - uop_ADD_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); - } - uop_MOVZX(ir, IREG_flags_res, IREG_8(fetchdat & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); + if (fetchdat & 0x38) { + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); + } else { + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - - if (fetchdat & 0x38) - { - uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); - } - else - { - uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); - } - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - if (fetchdat & 0x38) - { - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); - } - else - { - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); - } + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + if (fetchdat & 0x38) { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } else { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); } + } - return op_pc+1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_arith.h b/src/codegen_new/codegen_ops_arith.h index d1bbaa75d..176d4be7a 100644 --- a/src/codegen_new/codegen_ops_arith.h +++ b/src/codegen_new/codegen_ops_arith.h @@ -54,7 +54,6 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_new/codegen_ops_branch.c b/src/codegen_new/codegen_ops_branch.c index b05ce5bac..85ebd3f8e 100644 --- a/src/codegen_new/codegen_ops_branch.c +++ b/src/codegen_new/codegen_ops_branch.c @@ -13,1002 +13,977 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_mov.h" -static int NF_SET_01() +static int +NF_SET_01(void) { - return NF_SET() ? 1 : 0; + return NF_SET() ? 1 : 0; } -static int VF_SET_01() +static int +VF_SET_01(void) { - return VF_SET() ? 1 : 0; + return VF_SET() ? 1 : 0; } -static int ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +static int +ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Overflow is always zero*/ - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Overflow is always zero*/ + return 0; - case FLAGS_SUB8: case FLAGS_DEC8: - jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + case FLAGS_DEC8: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; - case FLAGS_SUB16: case FLAGS_DEC16: - jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; + case FLAGS_SUB16: + case FLAGS_DEC16: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; - case FLAGS_SUB32: case FLAGS_DEC32: - jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB32: + case FLAGS_DEC32: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; } -static int ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +static int +ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Overflow is always zero*/ - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Overflow is always zero*/ + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + return 0; - case FLAGS_SUB8: case FLAGS_DEC8: - jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + case FLAGS_DEC8: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; - case FLAGS_SUB16: case FLAGS_DEC16: - jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; + case FLAGS_SUB16: + case FLAGS_DEC16: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; - case FLAGS_SUB32: case FLAGS_DEC32: - jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB32: + case FLAGS_DEC32: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; +} + +static int +ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = (CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero*/ + return 0; + + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + if (do_unroll) jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - break; + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} +static int +ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = (!CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero*/ + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + return 0; + + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} + +static int +ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + + if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); } uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); - return 0; + } + return 0; +} +int +ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + + if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + } + return 0; } -static int ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +static int +ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; - int do_unroll = (CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop, jump_uop2 = -1; + int do_unroll = ((CF_SET() || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Carry is always zero*/ - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero, so test zero only*/ + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + break; - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: + case FLAGS_UNKNOWN: + default: + if (do_unroll) { uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} -static int ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = (!CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Carry is always zero*/ - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - return 0; - - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} - -static int ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - - if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) - { - if (!codegen_flags_changed || !flags_res_valid()) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } - else - { - if (!codegen_flags_changed || !flags_res_valid()) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - } - return 0; -} -int ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - - if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) - { - if (!codegen_flags_changed || !flags_res_valid()) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } - else - { - if (!codegen_flags_changed || !flags_res_valid()) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - } - return 0; -} - -static int ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop, jump_uop2 = -1; - int do_unroll = ((CF_SET() || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Carry is always zero, so test zero only*/ - if (do_unroll) - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - break; - - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - if (do_unroll) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - else - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - break; - } - if (do_unroll) - { - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 1; - } - else - { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; - } -} -static int ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop, jump_uop2 = -1; - int do_unroll = ((!CF_SET() && !ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Carry is always zero, so test zero only*/ - if (do_unroll) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - else - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - break; - - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - if (do_unroll) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - else - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - break; - } - if (do_unroll) - { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } - else - { - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 0; - } -} - -static int ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = (NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - break; - - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - break; - - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} -static int ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = (!NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - break; - - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - break; - - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} - -static int ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - - uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; -} -static int ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - - uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; -} - -static int ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = ((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - /*V flag is always clear. Condition is true if N is set*/ - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - break; - case FLAGS_ZN16: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - break; - case FLAGS_ZN32: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - break; - - case FLAGS_SUB8: case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - if (do_unroll) - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - else - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - break; - } - if (do_unroll) - uop_MOV_IMM(ir, IREG_pc, next_pc); - else - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} -static int ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - /*V flag is always clear. Condition is true if N is set*/ - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - break; - case FLAGS_ZN16: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - break; - case FLAGS_ZN32: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - break; - - case FLAGS_SUB8: case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - if (do_unroll) - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - else - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - break; - } - if (do_unroll) - uop_MOV_IMM(ir, IREG_pc, next_pc); - else - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} - -static int ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop, jump_uop2 = -1; - int do_unroll = (((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - if (do_unroll) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - } - else - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - } - break; - } - if (do_unroll) - { - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 1; - } - else - { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; - } -} -static int ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop, jump_uop2 = -1; - int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && !ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - if (do_unroll) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - } - else - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - } - break; - } - if (do_unroll) - { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } - else - { - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 0; - } -} - -#define ropJ(cond) \ -uint32_t ropJ ## cond ## _8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); \ - uint32_t dest_addr = op_pc + 1 + offset; \ - int ret; \ - \ - if (!(op_32 & 0x100)) \ - dest_addr &= 0xffff; \ - ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+1); \ - \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - return ret ? dest_addr : (op_pc+1); \ -} \ -uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); \ - uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ - int ret; \ - \ - ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+2); \ - \ - codegen_mark_code_present(block, cs+op_pc, 2); \ - return ret ? dest_addr : (op_pc+2); \ -} \ -uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uint32_t offset = fastreadl(cs + op_pc); \ - uint32_t dest_addr = op_pc + 4 + offset; \ - int ret; \ - \ - ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+4); \ - \ - codegen_mark_code_present(block, cs+op_pc, 4); \ - return ret ? dest_addr : (op_pc+4); \ -} - -ropJ(O) -ropJ(NO) -ropJ(B) -ropJ(NB) -ropJ(E) -ropJ(NE) -ropJ(BE) -ropJ(NBE) -ropJ(S) -ropJ(NS) -ropJ(P) -ropJ(NP) -ropJ(L) -ropJ(NL) -ropJ(LE) -ropJ(NLE) - - -uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - int jump_uop; - - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; - - if (op_32 & 0x200) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc+1; -} - -uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - uint32_t ret_addr; - int jump_uop; - - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; - - if (((op_32 & 0x200) ? ECX : CX) != 1 && codegen_can_unroll(block, ir, op_pc+1, dest_addr)) - { - if (op_32 & 0x200) - { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); - } - else - { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); - } - uop_MOV_IMM(ir, IREG_pc, op_pc+1); - ret_addr = dest_addr; - CPU_BLOCK_END(); - } - else - { - if (op_32 & 0x200) - { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); - } - else - { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - ret_addr = op_pc+1; - } - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - - codegen_mark_code_present(block, cs+op_pc, 1); - return ret_addr; -} - -uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - int jump_uop, jump_uop2; - - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; - - if (op_32 & 0x200) - { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); - } - else - { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); - } - if (!codegen_flags_changed || !flags_res_valid()) - { + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - } + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } + break; + } + if (do_unroll) { + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 1; + } else { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); - uop_NOP_BARRIER(ir); uop_set_jump_dest(ir, jump_uop); - uop_set_jump_dest(ir, jump_uop2); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc+1; + return 0; + } } -uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static int +ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - int jump_uop, jump_uop2; + int jump_uop, jump_uop2 = -1; + int do_unroll = ((!CF_SET() && !ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero, so test zero only*/ + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + break; - if (op_32 & 0x200) - { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); - } - else - { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); - } - if (!codegen_flags_changed || !flags_res_valid()) - { + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - } + } + break; + } + if (do_unroll) { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); - uop_NOP_BARRIER(ir); uop_set_jump_dest(ir, jump_uop); - uop_set_jump_dest(ir, jump_uop2); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc+1; + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 0; + } +} + +static int +ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = (NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + break; + + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + break; + + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} +static int +ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = (!NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + break; + + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + break; + + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} + +static int +ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + + uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; +} +static int +ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + + uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; +} + +static int +ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = ((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + /*V flag is always clear. Condition is true if N is set*/ + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + break; + case FLAGS_ZN16: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + break; + case FLAGS_ZN32: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + if (do_unroll) + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + else + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + if (do_unroll) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} +static int +ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + /*V flag is always clear. Condition is true if N is set*/ + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + break; + case FLAGS_ZN16: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + break; + case FLAGS_ZN32: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + if (do_unroll) + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + else + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + if (do_unroll) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} + +static int +ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop, jump_uop2 = -1; + int do_unroll = (((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + } + break; + } + if (do_unroll) { + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 1; + } else { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; + } +} +static int +ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop, jump_uop2 = -1; + int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && !ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + } + break; + } + if (do_unroll) { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 0; + } +} + +#define ropJ(cond) \ + uint32_t ropJ##cond##_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); \ + uint32_t dest_addr = op_pc + 1 + offset; \ + int ret; \ + \ + if (!(op_32 & 0x100)) \ + dest_addr &= 0xffff; \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 1); \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + return ret ? dest_addr : (op_pc + 1); \ + } \ + uint32_t ropJ##cond##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); \ + uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ + int ret; \ + \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 2); \ + \ + codegen_mark_code_present(block, cs + op_pc, 2); \ + return ret ? dest_addr : (op_pc + 2); \ + } \ + uint32_t ropJ##cond##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uint32_t offset = fastreadl(cs + op_pc); \ + uint32_t dest_addr = op_pc + 4 + offset; \ + int ret; \ + \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 4); \ + \ + codegen_mark_code_present(block, cs + op_pc, 4); \ + return ret ? dest_addr : (op_pc + 4); \ + } + +ropJ(O) + ropJ(NO) + ropJ(B) + ropJ(NB) + ropJ(E) + ropJ(NE) + ropJ(BE) + ropJ(NBE) + ropJ(S) + ropJ(NS) + ropJ(P) + ropJ(NP) + ropJ(L) + ropJ(NL) + ropJ(LE) + ropJ(NLE) + + uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + int jump_uop; + + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + + if (op_32 & 0x200) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} + +uint32_t +ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + uint32_t ret_addr; + int jump_uop; + + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + + if (((op_32 & 0x200) ? ECX : CX) != 1 && codegen_can_unroll(block, ir, op_pc + 1, dest_addr)) { + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); + } + uop_MOV_IMM(ir, IREG_pc, op_pc + 1); + ret_addr = dest_addr; + CPU_BLOCK_END(); + } else { + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + ret_addr = op_pc + 1; + } + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + + codegen_mark_code_present(block, cs + op_pc, 1); + return ret_addr; +} + +uint32_t +ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + int jump_uop, jump_uop2; + + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + uop_set_jump_dest(ir, jump_uop2); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} +uint32_t +ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + int jump_uop, jump_uop2; + + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + uop_set_jump_dest(ir, jump_uop2); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c index 598f63b80..e9739f830 100644 --- a/src/codegen_new/codegen_ops_fpu_arith.c +++ b/src/codegen_new/codegen_ops_fpu_arith.c @@ -14,562 +14,588 @@ #include "codegen_ops_fpu_arith.h" #include "codegen_ops_helpers.h" -uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - return op_pc; + return op_pc; } -uint32_t ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP2(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP2(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFUCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFUCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - return op_pc; + return op_pc; } -uint32_t ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFUCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFUCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP2(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP2(block, ir); - return op_pc; + return op_pc; } -#define ropF_arith_mem(name, load_uop) \ -uint32_t ropFADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - if ((cpu_state.npxc >> 10) & 3) \ - return 0; \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFCOM ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFCOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(block, ir); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFDIVR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFMUL ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFSUB ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFSUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} +#define ropF_arith_mem(name, load_uop) \ + uint32_t ropFADD##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + if ((cpu_state.npxc >> 10) & 3) \ + return 0; \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFCOM##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFCOMP##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(block, ir); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFDIV##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFDIVR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFMUL##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFSUB##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFSUBR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } ropF_arith_mem(s, uop_MEM_LOAD_SINGLE) -ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) + ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) -#define ropFI_arith_mem(name, temp_reg) \ -uint32_t ropFIADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFICOM ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFICOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(block, ir); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFIDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFIDIVR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)\ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFIMUL ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFISUB ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFISUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)\ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} +#define ropFI_arith_mem(name, temp_reg) \ + uint32_t ropFIADD##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFICOM##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFICOMP##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(block, ir); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIDIV##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIDIVR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIMUL##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFISUB##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFISUBR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } -ropFI_arith_mem(l, IREG_temp0) -ropFI_arith_mem(w, IREG_temp0_W) + ropFI_arith_mem(l, IREG_temp0) + ropFI_arith_mem(w, IREG_temp0_W) - -uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FABS(ir, IREG_ST(0), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FABS(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FCHS(ir, IREG_ST(0), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FCHS(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FSQRT(ir, IREG_ST(0), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSQRT(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + uop_FP_ENTER(ir); + uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - return op_pc; + return op_pc; } diff --git a/src/codegen_new/codegen_ops_fpu_constant.c b/src/codegen_new/codegen_ops_fpu_constant.c index fc59ae784..89c138637 100644 --- a/src/codegen_new/codegen_ops_fpu_constant.c +++ b/src/codegen_new/codegen_ops_fpu_constant.c @@ -14,23 +14,25 @@ #include "codegen_ops_fpu_constant.h" #include "codegen_ops_helpers.h" -uint32_t ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_temp0, 1); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_temp0, 1); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_temp0, 0); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_temp0, 0); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc; + return op_pc; } diff --git a/src/codegen_new/codegen_ops_fpu_loadstore.c b/src/codegen_new/codegen_ops_fpu_loadstore.c index 349d10de7..06709913d 100644 --- a/src/codegen_new/codegen_ops_fpu_loadstore.c +++ b/src/codegen_new/codegen_ops_fpu_loadstore.c @@ -14,221 +14,234 @@ #include "codegen_ops_fpu_arith.h" #include "codegen_ops_helpers.h" -uint32_t ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_SINGLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_SINGLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_DOUBLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_DOUBLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); - uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); + uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); - uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); + uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } - -uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0_W); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_ST_i64(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_ST_i64(-1)); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_ST_i64(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_ST_i64(-1)); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_ST_i64(0), IREG_tag(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_Q); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_ST_i64(0), IREG_tag(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_Q); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_fpu_misc.c b/src/codegen_new/codegen_ops_fpu_misc.c index cfe2ff698..cca9f4e4f 100644 --- a/src/codegen_new/codegen_ops_fpu_misc.c +++ b/src/codegen_new/codegen_ops_fpu_misc.c @@ -14,101 +14,109 @@ #include "codegen_ops_fpu_misc.h" #include "codegen_ops_helpers.h" -uint32_t ropFFREE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFFREE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_tag(dest_reg), TAG_EMPTY); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_tag(dest_reg), TAG_EMPTY); - return op_pc; + return op_pc; } -uint32_t ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_ST(-1), IREG_ST(src_reg)); - uop_MOV(ir, IREG_ST_i64(-1), IREG_ST_i64(src_reg)); - uop_MOV(ir, IREG_tag(-1), IREG_tag(src_reg)); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(-1), IREG_ST(src_reg)); + uop_MOV(ir, IREG_ST_i64(-1), IREG_ST_i64(src_reg)); + uop_MOV(ir, IREG_tag(-1), IREG_tag(src_reg)); + fpu_PUSH(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); - uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); + uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); - return op_pc; + return op_pc; } -uint32_t ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); - uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); + uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXC); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXC); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXS); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXS); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_AX, IREG_NPXS); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_AX, IREG_NPXS); - return op_pc; + return op_pc; } -uint32_t ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_temp0_D, IREG_ST(0)); - uop_MOV(ir, IREG_temp1_Q, IREG_ST_i64(0)); - uop_MOV(ir, IREG_temp2, IREG_tag(0)); - uop_MOV(ir, IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV(ir, IREG_ST_i64(0), IREG_ST_i64(dest_reg)); - uop_MOV(ir, IREG_tag(0), IREG_tag(dest_reg)); - uop_MOV(ir, IREG_ST(dest_reg), IREG_temp0_D); - uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_temp1_Q); - uop_MOV(ir, IREG_tag(dest_reg), IREG_temp2); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_temp0_D, IREG_ST(0)); + uop_MOV(ir, IREG_temp1_Q, IREG_ST_i64(0)); + uop_MOV(ir, IREG_temp2, IREG_tag(0)); + uop_MOV(ir, IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV(ir, IREG_ST_i64(0), IREG_ST_i64(dest_reg)); + uop_MOV(ir, IREG_tag(0), IREG_tag(dest_reg)); + uop_MOV(ir, IREG_ST(dest_reg), IREG_temp0_D); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_temp1_Q); + uop_MOV(ir, IREG_tag(dest_reg), IREG_temp2); - return op_pc; + return op_pc; } diff --git a/src/codegen_new/codegen_ops_helpers.c b/src/codegen_new/codegen_ops_helpers.c index 9c2280f07..242cbb818 100644 --- a/src/codegen_new/codegen_ops_helpers.c +++ b/src/codegen_new/codegen_ops_helpers.c @@ -11,65 +11,64 @@ #include "codegen_reg.h" #include "codegen_ops_helpers.h" -void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +void +LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - /*Word access that crosses two pages. Perform reads from both pages, shift and combine*/ - uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr)); - uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr+1)); - uop_SHL_IMM(ir, IREG_temp3_W, IREG_temp3_W, 8); - uop_OR(ir, dest_reg, dest_reg, IREG_temp3_W); + /*Word access that crosses two pages. Perform reads from both pages, shift and combine*/ + uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr)); + uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr + 1)); + uop_SHL_IMM(ir, IREG_temp3_W, IREG_temp3_W, 8); + uop_OR(ir, dest_reg, dest_reg, IREG_temp3_W); } -void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +void +LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - /*Dword access that crosses two pages. Perform reads from both pages, shift and combine*/ - uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr & ~3)); - uop_MOV_REG_PTR(ir, IREG_temp3, get_ram_ptr((addr + 4) & ~3)); - uop_SHR_IMM(ir, dest_reg, dest_reg, (addr & 3) * 8); - uop_SHL_IMM(ir, IREG_temp3, IREG_temp3, (4 - (addr & 3)) * 8); - uop_OR(ir, dest_reg, dest_reg, IREG_temp3); + /*Dword access that crosses two pages. Perform reads from both pages, shift and combine*/ + uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr & ~3)); + uop_MOV_REG_PTR(ir, IREG_temp3, get_ram_ptr((addr + 4) & ~3)); + uop_SHR_IMM(ir, dest_reg, dest_reg, (addr & 3) * 8); + uop_SHL_IMM(ir, IREG_temp3, IREG_temp3, (4 - (addr & 3)) * 8); + uop_OR(ir, dest_reg, dest_reg, IREG_temp3); } #define UNROLL_MAX_REG_REFERENCES 200 -#define UNROLL_MAX_UOPS 1000 -#define UNROLL_MAX_COUNT 10 -int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) +#define UNROLL_MAX_UOPS 1000 +#define UNROLL_MAX_COUNT 10 +int +codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { - int start; - int max_unroll; - int first_instruction; - int TOP = -1; + int start; + int max_unroll; + int first_instruction; + int TOP = -1; - /*Check that dest instruction was actually compiled into block*/ - start = codegen_get_instruction_uop(block, dest_addr, &first_instruction, &TOP); + /*Check that dest instruction was actually compiled into block*/ + start = codegen_get_instruction_uop(block, dest_addr, &first_instruction, &TOP); - /*Couldn't find any uOPs corresponding to the destination instruction*/ - if (start == -1) - { - /*Is instruction jumping to itself?*/ - if (dest_addr != cpu_state.oldpc) - { - return 0; - } - else - { - start = ir->wr_pos; - TOP = cpu_state.TOP; - } + /*Couldn't find any uOPs corresponding to the destination instruction*/ + if (start == -1) { + /*Is instruction jumping to itself?*/ + if (dest_addr != cpu_state.oldpc) { + return 0; + } else { + start = ir->wr_pos; + TOP = cpu_state.TOP; } + } - if (TOP != cpu_state.TOP) - return 0; + if (TOP != cpu_state.TOP) + return 0; - max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos-start)+6); - if ((max_version_refcount != 0) && (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount))) - max_unroll = (UNROLL_MAX_REG_REFERENCES / max_version_refcount); - if (max_unroll > UNROLL_MAX_COUNT) - max_unroll = UNROLL_MAX_COUNT; - if (max_unroll <= 1) - return 0; + max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos - start) + 6); + if ((max_version_refcount != 0) && (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount))) + max_unroll = (UNROLL_MAX_REG_REFERENCES / max_version_refcount); + if (max_unroll > UNROLL_MAX_COUNT) + max_unroll = UNROLL_MAX_COUNT; + if (max_unroll <= 1) + return 0; - codegen_ir_set_unroll(max_unroll, start, first_instruction); + codegen_ir_set_unroll(max_unroll, start, first_instruction); - return 1; + return 1; } diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 41ffe297f..5a8f1e1c7 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -1,126 +1,127 @@ #include "386_common.h" #include "codegen_backend.h" -static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) +static inline int +LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) { - if (stack32) - { - if (offset) - { - uop_ADD_IMM(ir, IREG_eaaddr, IREG_ESP, offset); - return IREG_eaaddr; - } - else - return IREG_ESP; - } - else - { - if (offset) - { - uop_ADD_IMM(ir, IREG_eaaddr_W, IREG_SP, offset); - uop_MOVZX(ir, IREG_eaaddr, IREG_eaaddr_W); - return IREG_eaaddr; - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - return IREG_eaaddr; - } + if (stack32) { + if (offset) { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_ESP, offset); + return IREG_eaaddr; + } else + return IREG_ESP; + } else { + if (offset) { + uop_ADD_IMM(ir, IREG_eaaddr_W, IREG_SP, offset); + uop_MOVZX(ir, IREG_eaaddr, IREG_eaaddr_W); + return IREG_eaaddr; + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + return IREG_eaaddr; } + } } -static inline int LOAD_SP(ir_data_t *ir) +static inline int +LOAD_SP(ir_data_t *ir) { - return LOAD_SP_WITH_OFFSET(ir, 0); + return LOAD_SP_WITH_OFFSET(ir, 0); } -static inline void ADD_SP(ir_data_t *ir, int offset) +static inline void +ADD_SP(ir_data_t *ir, int offset) { - if (stack32) - uop_ADD_IMM(ir, IREG_ESP, IREG_ESP, offset); - else - uop_ADD_IMM(ir, IREG_SP, IREG_SP, offset); + if (stack32) + uop_ADD_IMM(ir, IREG_ESP, IREG_ESP, offset); + else + uop_ADD_IMM(ir, IREG_SP, IREG_SP, offset); } -static inline void SUB_SP(ir_data_t *ir, int offset) +static inline void +SUB_SP(ir_data_t *ir, int offset) { - if (stack32) - uop_SUB_IMM(ir, IREG_ESP, IREG_ESP, offset); - else - uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset); + if (stack32) + uop_SUB_IMM(ir, IREG_ESP, IREG_ESP, offset); + else + uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset); } -static inline void fpu_POP(codeblock_t *block, ir_data_t *ir) +static inline void +fpu_POP(codeblock_t *block, ir_data_t *ir) { - if (block->flags & CODEBLOCK_STATIC_TOP) - uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 1); - else - uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); + if (block->flags & CODEBLOCK_STATIC_TOP) + uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 1); + else + uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); } -static inline void fpu_POP2(codeblock_t *block, ir_data_t *ir) +static inline void +fpu_POP2(codeblock_t *block, ir_data_t *ir) { - if (block->flags & CODEBLOCK_STATIC_TOP) - uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 2); - else - uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 2); + if (block->flags & CODEBLOCK_STATIC_TOP) + uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 2); + else + uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 2); } -static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir) +static inline void +fpu_PUSH(codeblock_t *block, ir_data_t *ir) { - if (block->flags & CODEBLOCK_STATIC_TOP) - uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP - 1); - else - uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); + if (block->flags & CODEBLOCK_STATIC_TOP) + uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP - 1); + else + uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); } -static inline void CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) +static inline void +CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || - (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + return; - uop_CMP_JB(ir, addr_reg, ireg_seg_limit_low(seg), codegen_gpf_rout); - if (end_offset) - { - uop_ADD_IMM(ir, IREG_temp3, addr_reg, end_offset); - uop_CMP_JNBE(ir, IREG_temp3, ireg_seg_limit_high(seg), codegen_gpf_rout); - } - else - uop_CMP_JNBE(ir, addr_reg, ireg_seg_limit_high(seg), codegen_gpf_rout); + uop_CMP_JB(ir, addr_reg, ireg_seg_limit_low(seg), codegen_gpf_rout); + if (end_offset) { + uop_ADD_IMM(ir, IREG_temp3, addr_reg, end_offset); + uop_CMP_JNBE(ir, IREG_temp3, ireg_seg_limit_high(seg), codegen_gpf_rout); + } else + uop_CMP_JNBE(ir, addr_reg, ireg_seg_limit_high(seg), codegen_gpf_rout); } -static inline void LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +static inline void +LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr)); + uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr)); } void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr); -static inline void LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +static inline void +LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - if ((addr & 0xfff) == 0xfff) - LOAD_IMMEDIATE_FROM_RAM_16_unaligned(block, ir, dest_reg, addr); - else - uop_MOVZX_REG_PTR_16(ir, dest_reg, get_ram_ptr(addr)); + if ((addr & 0xfff) == 0xfff) + LOAD_IMMEDIATE_FROM_RAM_16_unaligned(block, ir, dest_reg, addr); + else + uop_MOVZX_REG_PTR_16(ir, dest_reg, get_ram_ptr(addr)); } void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr); -static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +static inline void +LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - if ((addr & 0xfff) >= 0xffd) - LOAD_IMMEDIATE_FROM_RAM_32_unaligned(block, ir, dest_reg, addr); - else - uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr)); + if ((addr & 0xfff) >= 0xffd) + LOAD_IMMEDIATE_FROM_RAM_32_unaligned(block, ir, dest_reg, addr); + else + uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr)); } int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr); -static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) +static inline int +codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { - if (block->flags & CODEBLOCK_BYTE_MASK) - return 0; + if (block->flags & CODEBLOCK_BYTE_MASK) + return 0; - /*Is dest within block?*/ - if (dest_addr > next_pc) - return 0; - if ((cs+dest_addr) < block->pc) - return 0; + /*Is dest within block?*/ + if (dest_addr > next_pc) + return 0; + if ((cs + dest_addr) < block->pc) + return 0; - return codegen_can_unroll_full(block, ir, next_pc, dest_addr); + return codegen_can_unroll_full(block, ir, next_pc, dest_addr); } diff --git a/src/codegen_new/codegen_ops_jump.c b/src/codegen_new/codegen_ops_jump.c index f672b40ca..0bd4db24a 100644 --- a/src/codegen_new/codegen_ops_jump.c +++ b/src/codegen_new/codegen_ops_jump.c @@ -11,282 +11,281 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_mov.h" -uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc+1+offset; - - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; - - if (offset < 0) - codegen_can_unroll(block, ir, op_pc+1, dest_addr); - codegen_mark_code_present(block, cs+op_pc, 1); - return dest_addr; -} -uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); - uint32_t dest_addr = op_pc+2+offset; + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + if (!(op_32 & 0x100)) dest_addr &= 0xffff; - if (offset < 0) - codegen_can_unroll(block, ir, op_pc+1, dest_addr); - codegen_mark_code_present(block, cs+op_pc, 2); - return dest_addr; + if (offset < 0) + codegen_can_unroll(block, ir, op_pc + 1, dest_addr); + codegen_mark_code_present(block, cs + op_pc, 1); + return dest_addr; } -uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = fastreadl(cs + op_pc); - uint32_t dest_addr = op_pc+4+offset; + uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); + uint32_t dest_addr = op_pc + 2 + offset; - if (offset < 0) - codegen_can_unroll(block, ir, op_pc+1, dest_addr); - codegen_mark_code_present(block, cs+op_pc, 4); - return dest_addr; + dest_addr &= 0xffff; + + if (offset < 0) + codegen_can_unroll(block, ir, op_pc + 1, dest_addr); + codegen_mark_code_present(block, cs + op_pc, 2); + return dest_addr; } - -uint32_t ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t new_pc = fastreadw(cs + op_pc); - uint16_t new_cs = fastreadw(cs + op_pc + 2); + uint32_t offset = fastreadl(cs + op_pc); + uint32_t dest_addr = op_pc + 4 + offset; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_MOV_IMM(ir, IREG_pc, new_pc); - uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); - uop_CALL_FUNC(ir, loadcsjmp); - - codegen_mark_code_present(block, cs+op_pc, 4); - return -1; + if (offset < 0) + codegen_can_unroll(block, ir, op_pc + 1, dest_addr); + codegen_mark_code_present(block, cs + op_pc, 4); + return dest_addr; } -uint32_t ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t new_pc = fastreadl(cs + op_pc); - uint16_t new_cs = fastreadw(cs + op_pc + 4); + uint16_t new_pc = fastreadw(cs + op_pc); + uint16_t new_cs = fastreadw(cs + op_pc + 2); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_MOV_IMM(ir, IREG_pc, new_pc); - uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); - uop_CALL_FUNC(ir, loadcsjmp); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_pc, new_pc); + uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); + uop_CALL_FUNC(ir, loadcsjmp); - codegen_mark_code_present(block, cs+op_pc, 6); - return -1; + codegen_mark_code_present(block, cs + op_pc, 4); + return -1; } - -uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); - uint16_t ret_addr = op_pc + 2; - uint16_t dest_addr = ret_addr + offset; - int sp_reg; + uint32_t new_pc = fastreadl(cs + op_pc); + uint16_t new_cs = fastreadw(cs + op_pc + 4); - dest_addr &= 0xffff; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_pc, new_pc); + uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); + uop_CALL_FUNC(ir, loadcsjmp); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr); - SUB_SP(ir, 2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 6); + return -1; } -uint32_t ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = fastreadl(cs + op_pc); - uint32_t ret_addr = op_pc + 4; - uint32_t dest_addr = ret_addr + offset; - int sp_reg; + uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); + uint16_t ret_addr = op_pc + 2; + uint16_t dest_addr = ret_addr + offset; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, ret_addr); - SUB_SP(ir, 4); - uop_MOV_IMM(ir, IREG_pc, dest_addr); + dest_addr &= 0xffff; - codegen_mark_code_present(block, cs+op_pc, 4); - return -1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr); + SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } - -uint32_t ropRET_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uint32_t offset = fastreadl(cs + op_pc); + uint32_t ret_addr = op_pc + 4; + uint32_t dest_addr = ret_addr + offset; + int sp_reg; - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 2); - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, ret_addr); + SUB_SP(ir, 4); + uop_MOV_IMM(ir, IREG_pc, dest_addr); - return -1; + codegen_mark_code_present(block, cs + op_pc, 4); + return -1; } -uint32_t ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropRET_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 4); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 2); + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - return -1; + return -1; } - -uint32_t ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 4); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 2+offset); - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + return -1; } -uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset = fastreadw(cs + op_pc); + uint16_t offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 4+offset); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 2 + offset); + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } - -uint32_t ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) - return 0; + uint16_t offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - { - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); - } - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 4); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 4 + offset); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } -uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) - return 0; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - { - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); - } - uop_MOV(ir, IREG_pc, IREG_temp0); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 8); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); + } + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 4); - return -1; + return -1; } - -uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) - return 0; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); + } + uop_MOV(ir, IREG_pc, IREG_temp0); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 8); - if (stack32) - { - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); - } - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 4+offset); - - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + return -1; } -uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset; + uint16_t offset; - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) - return 0; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - { - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); - } - uop_MOV(ir, IREG_pc, IREG_temp0); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 8+offset); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); + } + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 4 + offset); - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; +} +uint32_t +ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t offset; + + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; + + offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); + } + uop_MOV(ir, IREG_pc, IREG_temp0); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 8 + offset); + + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } diff --git a/src/codegen_new/codegen_ops_logic.c b/src/codegen_new/codegen_ops_logic.c index dd02bd3f9..6db452a45 100644 --- a/src/codegen_new/codegen_ops_logic.c +++ b/src/codegen_new/codegen_ops_logic.c @@ -12,796 +12,754 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_logic.h" -uint32_t ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_AND_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_AND_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_AND_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_AND_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_AND(ir, IREG_EAX, IREG_EAX, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_AND(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - return op_pc + 4; + codegen_flags_changed = 1; + return op_pc + 4; } -uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_OR_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_OR_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_OR_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_OR_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_OR(ir, IREG_EAX, IREG_EAX, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_OR(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } -uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, dest_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, dest_reg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_AND(ir, IREG_flags_res, IREG_EAX, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_AND(ir, IREG_flags_res, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } -uint32_t ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_XOR_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_XOR_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_XOR_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_XOR_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_XOR(ir, IREG_EAX, IREG_EAX, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_XOR(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } -uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, dest_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, dest_reg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + + codegen_flags_changed = 1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_misc.c b/src/codegen_new/codegen_ops_misc.c index adb478d13..7f7613dbf 100644 --- a/src/codegen_new/codegen_ops_misc.c +++ b/src/codegen_new/codegen_ops_misc.c @@ -12,603 +12,591 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_misc.h" -uint32_t ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) == 0xc0) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - uop_MOV(ir, IREG_16(dest_reg), IREG_eaaddr_W); - - return op_pc + 1; -} -uint32_t ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - if ((fetchdat & 0xc0) == 0xc0) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - uop_MOV(ir, IREG_32(dest_reg), IREG_eaaddr); - - return op_pc + 1; -} - -uint32_t ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - uint8_t imm_data; - int reg; - - if (fetchdat & 0x20) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - reg = IREG_8(fetchdat & 7); - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - reg = IREG_temp0_B; - } - - switch (fetchdat & 0x38) - { - case 0x00: case 0x08: /*TEST*/ - imm_data = fastreadb(cs + op_pc + 1); - - uop_AND_IMM(ir, IREG_flags_res_B, reg, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc+2; - - case 0x10: /*NOT*/ - uop_XOR_IMM(ir, reg, reg, 0xff); - if ((fetchdat & 0xc0) != 0xc0) - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - - codegen_flags_changed = 1; - return op_pc+1; - - case 0x18: /*NEG*/ - uop_MOV_IMM(ir, IREG_temp1_B, 0); - - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op2, reg); - uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - uop_MOV(ir, reg, IREG_temp1_B); - } - else - { - uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOV_IMM(ir, IREG_flags_op1, 0); - - codegen_flags_changed = 1; - return op_pc+1; - } + if ((fetchdat & 0xc0) == 0xc0) return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + uop_MOV(ir, IREG_16(dest_reg), IREG_eaaddr_W); + + return op_pc + 1; } -uint32_t ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - uint16_t imm_data; - int reg; + int dest_reg = (fetchdat >> 3) & 7; - if (fetchdat & 0x20) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - reg = IREG_16(fetchdat & 7); - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - reg = IREG_temp0_W; - } - - switch (fetchdat & 0x38) - { - case 0x00: case 0x08: /*TEST*/ - imm_data = fastreadw(cs + op_pc + 1); - - uop_AND_IMM(ir, IREG_flags_res_W, reg, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 2); - return op_pc+3; - - case 0x10: /*NOT*/ - uop_XOR_IMM(ir, reg, reg, 0xffff); - if ((fetchdat & 0xc0) != 0xc0) - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - - codegen_flags_changed = 1; - return op_pc+1; - - case 0x18: /*NEG*/ - uop_MOV_IMM(ir, IREG_temp1_W, 0); - - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op2, reg); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - uop_MOV(ir, reg, IREG_temp1_W); - } - else - { - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOV_IMM(ir, IREG_flags_op1, 0); - - codegen_flags_changed = 1; - return op_pc+1; - } + if ((fetchdat & 0xc0) == 0xc0) return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + uop_MOV(ir, IREG_32(dest_reg), IREG_eaaddr); + + return op_pc + 1; } -uint32_t ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - uint32_t imm_data; - int reg; + x86seg *target_seg = NULL; + uint8_t imm_data; + int reg; - if (fetchdat & 0x20) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - reg = IREG_32(fetchdat & 7); - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - reg = IREG_temp0; - } - - switch (fetchdat & 0x38) - { - case 0x00: case 0x08: /*TEST*/ - imm_data = fastreadl(cs + op_pc + 1); - - uop_AND_IMM(ir, IREG_flags_res, reg, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 4); - return op_pc+5; - - case 0x10: /*NOT*/ - uop_XOR_IMM(ir, reg, reg, 0xffffffff); - if ((fetchdat & 0xc0) != 0xc0) - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - - codegen_flags_changed = 1; - return op_pc+1; - - case 0x18: /*NEG*/ - uop_MOV_IMM(ir, IREG_temp1, 0); - - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOV(ir, IREG_flags_op2, reg); - uop_SUB(ir, IREG_temp1, IREG_temp1, reg); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - uop_MOV(ir, reg, IREG_temp1); - } - else - { - uop_SUB(ir, IREG_temp1, IREG_temp1, reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV_IMM(ir, IREG_flags_op1, 0); - - codegen_flags_changed = 1; - return op_pc+1; - } + if (fetchdat & 0x20) return 0; -} -static void rebuild_c(ir_data_t *ir) -{ - int needs_rebuild = 1; - - if (codegen_flags_changed) - { - switch (cpu_state.flags_op) - { - case FLAGS_INC8: case FLAGS_INC16: case FLAGS_INC32: - case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: - needs_rebuild = 0; - break; - } - } - - if (needs_rebuild) - { - uop_CALL_FUNC(ir, flags_rebuild_c); - } -} - -uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - int src_reg, sp_reg; - - if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - if ((fetchdat & 0x38) == 0x28) - return 0; - src_reg = IREG_16(fetchdat & 7); - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_8(fetchdat & 7); + else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if (!(fetchdat & 0x30)) /*INC/DEC*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - src_reg = IREG_temp0_W; - } + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0_B; + } - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + switch (fetchdat & 0x38) { + case 0x00: + case 0x08: /*TEST*/ + imm_data = fastreadb(cs + op_pc + 1); - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_ADD_IMM(ir, src_reg, src_reg, 1); - uop_MOVZX(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); - } - else - { - uop_ADD_IMM(ir, IREG_temp1_W, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); - } - return op_pc+1; + uop_AND_IMM(ir, IREG_flags_res_B, reg, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - case 0x08: /*DEC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_SUB_IMM(ir, src_reg, src_reg, 1); - uop_MOVZX(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); - } - else - { - uop_SUB_IMM(ir, IREG_temp1_W, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); - } - return op_pc+1; + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - case 0x10: /*CALL*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, op_pc + 1); - SUB_SP(ir, 2); - uop_MOVZX(ir, IREG_pc, src_reg); - return -1; + codegen_flags_changed = 1; + return op_pc + 1; - case 0x20: /*JMP*/ - uop_MOVZX(ir, IREG_pc, src_reg); - return -1; + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1_B, 0); - case 0x28: /*JMP far*/ - uop_MOVZX(ir, IREG_pc, src_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); - uop_CALL_FUNC(ir, loadcsjmp); - return -1; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + uop_MOV(ir, reg, IREG_temp1_B); + } else { + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOV_IMM(ir, IREG_flags_op1, 0); - case 0x30: /*PUSH*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); - SUB_SP(ir, 2); - return op_pc+1; - } - return 0; + codegen_flags_changed = 1; + return op_pc + 1; + } + return 0; } - -uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - int src_reg, sp_reg; + x86seg *target_seg = NULL; + uint16_t imm_data; + int reg; - if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) - return 0; + if (fetchdat & 0x20) + return 0; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - if ((fetchdat & 0x38) == 0x28) - return 0; - src_reg = IREG_32(fetchdat & 7); - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_16(fetchdat & 7); + else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if (!(fetchdat & 0x30)) /*INC/DEC*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - src_reg = IREG_temp0; - } + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0_W; + } - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + switch (fetchdat & 0x38) { + case 0x00: + case 0x08: /*TEST*/ + imm_data = fastreadw(cs + op_pc + 1); - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_ADD_IMM(ir, src_reg, src_reg, 1); - uop_MOV(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); - } - else - { - uop_ADD_IMM(ir, IREG_temp1, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); - } - return op_pc+1; + uop_AND_IMM(ir, IREG_flags_res_W, reg, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - case 0x08: /*DEC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 2); + return op_pc + 3; - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_SUB_IMM(ir, src_reg, src_reg, 1); - uop_MOV(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); - } - else - { - uop_SUB_IMM(ir, IREG_temp1, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); - } - return op_pc+1; + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xffff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - case 0x10: /*CALL*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, op_pc + 1); - SUB_SP(ir, 4); - uop_MOV(ir, IREG_pc, src_reg); - return -1; + codegen_flags_changed = 1; + return op_pc + 1; - case 0x20: /*JMP*/ - uop_MOV(ir, IREG_pc, src_reg); - return -1; + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1_W, 0); - case 0x28: /*JMP far*/ - uop_MOV(ir, IREG_pc, src_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); - uop_CALL_FUNC(ir, loadcsjmp); - return -1; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV(ir, reg, IREG_temp1_W); + } else { + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOV_IMM(ir, IREG_flags_op1, 0); - case 0x30: /*PUSH*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); - SUB_SP(ir, 4); - return op_pc+1; - } + codegen_flags_changed = 1; + return op_pc + 1; + } + return 0; +} +uint32_t +ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint32_t imm_data; + int reg; + + if (fetchdat & 0x20) return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_32(fetchdat & 7); + else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0; + } + + switch (fetchdat & 0x38) { + case 0x00: + case 0x08: /*TEST*/ + imm_data = fastreadl(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_flags_res, reg, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 4); + return op_pc + 5; + + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xffffffff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); + + codegen_flags_changed = 1; + return op_pc + 1; + + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1, 0); + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1, IREG_temp1, reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV(ir, reg, IREG_temp1); + } else { + uop_SUB(ir, IREG_temp1, IREG_temp1, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV_IMM(ir, IREG_flags_op1, 0); + + codegen_flags_changed = 1; + return op_pc + 1; + } + return 0; } -uint32_t ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static void +rebuild_c(ir_data_t *ir) { - return op_pc; + int needs_rebuild = 1; + + if (codegen_flags_changed) { + switch (cpu_state.flags_op) { + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } + + if (needs_rebuild) { + uop_CALL_FUNC(ir, flags_rebuild_c); + } } -uint32_t ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOVSX(ir, IREG_AX, IREG_AL); + x86seg *target_seg = NULL; + int src_reg, sp_reg; - return op_pc; + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if ((fetchdat & 0x38) == 0x28) + return 0; + src_reg = IREG_16(fetchdat & 7); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0_W; + } + + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } else { + uop_ADD_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } + return op_pc + 1; + + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } else { + uop_SUB_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } + return op_pc + 1; + + case 0x10: /*CALL*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, op_pc + 1); + SUB_SP(ir, 2); + uop_MOVZX(ir, IREG_pc, src_reg); + return -1; + + case 0x20: /*JMP*/ + uop_MOVZX(ir, IREG_pc, src_reg); + return -1; + + case 0x28: /*JMP far*/ + uop_MOVZX(ir, IREG_pc, src_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); + uop_CALL_FUNC(ir, loadcsjmp); + return -1; + + case 0x30: /*PUSH*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); + SUB_SP(ir, 2); + return op_pc + 1; + } + return 0; } -uint32_t ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_SAR_IMM(ir, IREG_EDX, IREG_EAX, 31); + x86seg *target_seg = NULL; + int src_reg, sp_reg; - return op_pc; + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if ((fetchdat & 0x38) == 0x28) + return 0; + src_reg = IREG_32(fetchdat & 7); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0; + } + + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } else { + uop_ADD_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } + return op_pc + 1; + + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } else { + uop_SUB_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } + return op_pc + 1; + + case 0x10: /*CALL*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, op_pc + 1); + SUB_SP(ir, 4); + uop_MOV(ir, IREG_pc, src_reg); + return -1; + + case 0x20: /*JMP*/ + uop_MOV(ir, IREG_pc, src_reg); + return -1; + + case 0x28: /*JMP far*/ + uop_MOV(ir, IREG_pc, src_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); + uop_CALL_FUNC(ir, loadcsjmp); + return -1; + + case 0x30: /*PUSH*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); + SUB_SP(ir, 4); + return op_pc + 1; + } + return 0; } -uint32_t ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_SAR_IMM(ir, IREG_DX, IREG_AX, 15); - - return op_pc; + return op_pc; } -uint32_t ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOVSX(ir, IREG_EAX, IREG_AX); + uop_MOVSX(ir, IREG_AX, IREG_AL); - return op_pc; + return op_pc; +} +uint32_t +ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_SAR_IMM(ir, IREG_EDX, IREG_EAX, 31); + + return op_pc; +} +uint32_t +ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_SAR_IMM(ir, IREG_DX, IREG_AX, 15); + + return op_pc; +} +uint32_t +ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOVSX(ir, IREG_EAX, IREG_AX); + + return op_pc; } -#define ropLxS(name, seg) \ -uint32_t rop ## name ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg = NULL; \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ - uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ - uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ - \ - if (seg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); \ - \ - return op_pc + 1; \ -} \ -uint32_t rop ## name ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg = NULL; \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ - uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ - uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ - \ - if (seg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); \ - \ - return op_pc + 1; \ -} +#define ropLxS(name, seg) \ + uint32_t rop##name##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ + } \ + uint32_t rop##name##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ + } ropLxS(LDS, &cpu_state.seg_ds) -ropLxS(LES, &cpu_state.seg_es) -ropLxS(LFS, &cpu_state.seg_fs) -ropLxS(LGS, &cpu_state.seg_gs) -ropLxS(LSS, &cpu_state.seg_ss) + ropLxS(LES, &cpu_state.seg_es) + ropLxS(LFS, &cpu_state.seg_fs) + ropLxS(LGS, &cpu_state.seg_gs) + ropLxS(LSS, &cpu_state.seg_ss) -uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_CALL_FUNC(ir, flags_rebuild); - uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); - return op_pc; + uop_CALL_FUNC(ir, flags_rebuild); + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); + return op_pc; } -uint32_t ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_CALL_FUNC(ir, flags_rebuild); - uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); - return op_pc; + uop_CALL_FUNC(ir, flags_rebuild); + uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; } -uint32_t ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_CALL_FUNC(ir, flags_rebuild); - uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); - return op_pc; + uop_CALL_FUNC(ir, flags_rebuild); + uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; } -uint32_t ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); - return op_pc; + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); + return op_pc; } -uint32_t ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); - return op_pc; + uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); + return op_pc; } -uint32_t ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; - uop_AND_IMM(ir, IREG_flags, IREG_flags, ~I_FLAG); - return op_pc; + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~I_FLAG); + return op_pc; } -uint32_t ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; - uop_OR_IMM(ir, IREG_flags, IREG_flags, I_FLAG); - return op_pc; + uop_OR_IMM(ir, IREG_flags, IREG_flags, I_FLAG); + return op_pc; } diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index 66124ca5e..b352c402a 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -13,32 +13,30 @@ #include "codegen_ops_mmx_arith.h" #include "codegen_ops_helpers.h" -#define ropParith(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ -} +#define ropParith(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ + } +// clang-format off ropParith(PADDB) ropParith(PADDW) ropParith(PADDD) @@ -58,3 +56,4 @@ ropParith(PSUBUSW) ropParith(PMADDWD) ropParith(PMULHW) ropParith(PMULLW) +// clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index 29a28e14f..c8d4909f9 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -13,35 +13,34 @@ #include "codegen_ops_mmx_cmp.h" #include "codegen_ops_helpers.h" -#define ropPcmp(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ -} +#define ropPcmp(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ + } +// clang-format off ropPcmp(PCMPEQB) ropPcmp(PCMPEQW) ropPcmp(PCMPEQD) ropPcmp(PCMPGTB) ropPcmp(PCMPGTW) ropPcmp(PCMPGTD) +// clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index ebdf81555..a20e18e68 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -13,104 +13,96 @@ #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_helpers.h" -uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_MM(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_MM(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - if (cpu_iscyrix && in_smm) - return 0; + if (cpu_iscyrix && in_smm) + return 0; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); - uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); + uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); + } - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index 24dc2b4c7..664bfd14c 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -13,99 +13,91 @@ #include "codegen_ops_mmx_logic.h" #include "codegen_ops_helpers.h" -uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index 87b562d17..99016352e 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -13,32 +13,30 @@ #include "codegen_ops_mmx_pack.h" #include "codegen_ops_helpers.h" -#define ropPpack(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ -} +#define ropPpack(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ + } +// clang-format off ropPpack(PACKSSWB) ropPpack(PACKSSDW) ropPpack(PACKUSWB) @@ -48,3 +46,4 @@ ropPpack(PUNPCKLDQ) ropPpack(PUNPCKHBW) ropPpack(PUNPCKHWD) ropPpack(PUNPCKHDQ) +// clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c index bb5277ef3..32449d188 100644 --- a/src/codegen_new/codegen_ops_mmx_shift.c +++ b/src/codegen_new/codegen_ops_mmx_shift.c @@ -13,84 +13,81 @@ #include "codegen_ops_mmx_shift.h" #include "codegen_ops_helpers.h" -uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = fastreadb(cs + op_pc + 1); + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - switch (op) - { - case 0x10: /*PSRLW*/ - uop_PSRLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x20: /*PSRAW*/ - uop_PSRAW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x30: /*PSLLW*/ - uop_PSLLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - default: - return 0; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + switch (op) { + case 0x10: /*PSRLW*/ + uop_PSRLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAW*/ + uop_PSRAW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLW*/ + uop_PSLLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + } - } - - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = fastreadb(cs + op_pc + 1); + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - switch (op) - { - case 0x10: /*PSRLD*/ - uop_PSRLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x20: /*PSRAD*/ - uop_PSRAD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x30: /*PSLLD*/ - uop_PSLLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - default: - return 0; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + switch (op) { + case 0x10: /*PSRLD*/ + uop_PSRLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAD*/ + uop_PSRAD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLD*/ + uop_PSLLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + } - } - - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = fastreadb(cs + op_pc + 1); + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - switch (op) - { - case 0x10: /*PSRLQ*/ - uop_PSRLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x20: /*PSRAQ*/ - uop_PSRAQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x30: /*PSLLQ*/ - uop_PSLLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - default: - return 0; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + switch (op) { + case 0x10: /*PSRLQ*/ + uop_PSRLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAQ*/ + uop_PSRAQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLQ*/ + uop_PSLLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + } - } - - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } diff --git a/src/codegen_new/codegen_ops_mov.c b/src/codegen_new/codegen_ops_mov.c index eb748a027..68e8fb011 100644 --- a/src/codegen_new/codegen_ops_mov.c +++ b/src/codegen_new/codegen_ops_mov.c @@ -11,763 +11,718 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_mov.h" -uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm = fastreadb(cs + op_pc); + uint8_t imm = fastreadb(cs + op_pc); - uop_MOV_IMM(ir, IREG_8(opcode & 7), imm); + uop_MOV_IMM(ir, IREG_8(opcode & 7), imm); - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm = fastreadw(cs + op_pc); + uint16_t imm = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_16(opcode & 7), imm); + uop_MOV_IMM(ir, IREG_16(opcode & 7), imm); - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_32(opcode & 7), cs + op_pc); - } - else - { - fetchdat = fastreadl(cs + op_pc); - uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); - codegen_mark_code_present(block, cs+op_pc, 4); - } - return op_pc + 4; + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_32(opcode & 7), cs + op_pc); + } else { + fetchdat = fastreadl(cs + op_pc); + uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); + codegen_mark_code_present(block, cs + op_pc, 4); + } + return op_pc + 4; } - - -uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 0); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); - } - - return op_pc + 1; -} -uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); - } - - return op_pc + 1; -} -uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); - } - - return op_pc + 1; -} -uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } - - return op_pc + 1; -} -uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } - - return op_pc + 1; -} -uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } - - return op_pc + 1; -} - -uint32_t ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_read(block, ir, op_ea_seg); - uop_MEM_LOAD_ABS(ir, IREG_AL, ireg_seg_base(op_ea_seg), addr); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -uint32_t ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_read(block, ir, op_ea_seg); - uop_MEM_LOAD_ABS(ir, IREG_AX, ireg_seg_base(op_ea_seg), addr); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -uint32_t ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr = 0; - - if (op_32 & 0x200) - { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + op_pc); - } - else - { - addr = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - } - } - else - { - addr = fastreadw(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 2); - } - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_read(block, ir, op_ea_seg); - if ((block->flags & CODEBLOCK_NO_IMMEDIATES) && (op_32 & 0x200)) - uop_MEM_LOAD_REG(ir, IREG_EAX, ireg_seg_base(op_ea_seg), IREG_eaaddr); - else - uop_MEM_LOAD_ABS(ir, IREG_EAX, ireg_seg_base(op_ea_seg), addr); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -uint32_t ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_write(block, ir, op_ea_seg); - uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AL); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -uint32_t ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_write(block, ir, op_ea_seg); - uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AX); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -uint32_t ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_write(block, ir, op_ea_seg); - uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_EAX); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); + } else { x86seg *target_seg; - uint8_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - imm = fastreadb(cs + op_pc + 1); - uop_MOV_IMM(ir, IREG_8(dest_reg), imm); - } - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadb(cs + op_pc + 1); - uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); - } - - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; -} -uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg; - uint16_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - imm = fastreadw(cs + op_pc + 1); - uop_MOV_IMM(ir, IREG_16(dest_reg), imm); - } - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadw(cs + op_pc + 1); - uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); - } - - codegen_mark_code_present(block, cs+op_pc+1, 2); - return op_pc + 3; -} -uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg; - uint32_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - imm = fastreadl(cs + op_pc + 1); - uop_MOV_IMM(ir, IREG_32(dest_reg), imm); - } - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadl(cs + op_pc + 1); - uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); - } - - codegen_mark_code_present(block, cs+op_pc+1, 4); - return op_pc + 5; -} - -uint32_t ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg; - - codegen_mark_code_present(block, cs+op_pc, 1); - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - src_reg = IREG_ES_seg_W; - break; - case 0x08: /*CS*/ - src_reg = IREG_CS_seg_W; - break; - case 0x18: /*DS*/ - src_reg = IREG_DS_seg_W; - break; - case 0x10: /*SS*/ - src_reg = IREG_SS_seg_W; - break; - case 0x20: /*FS*/ - src_reg = IREG_FS_seg_W; - break; - case 0x28: /*GS*/ - src_reg = IREG_GS_seg_W; - break; - default: - return 0; - } - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_16(dest_reg), src_reg); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); - } - - return op_pc + 1; -} -uint32_t ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg; - - codegen_mark_code_present(block, cs+op_pc, 1); - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - src_reg = IREG_ES_seg_W; - break; - case 0x08: /*CS*/ - src_reg = IREG_CS_seg_W; - break; - case 0x18: /*DS*/ - src_reg = IREG_DS_seg_W; - break; - case 0x10: /*SS*/ - src_reg = IREG_SS_seg_W; - break; - case 0x20: /*FS*/ - src_reg = IREG_FS_seg_W; - break; - case 0x28: /*GS*/ - src_reg = IREG_GS_seg_W; - break; - default: - return 0; - } - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), src_reg); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); - } - - return op_pc + 1; -} - -uint32_t ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg; - x86seg *rseg; - - codegen_mark_code_present(block, cs+op_pc, 1); - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - rseg = &cpu_state.seg_es; - break; - case 0x18: /*DS*/ - rseg = &cpu_state.seg_ds; - break; - case 0x20: /*FS*/ - rseg = &cpu_state.seg_fs; - break; - case 0x28: /*GS*/ - rseg = &cpu_state.seg_gs; - break; - default: - return 0; - } uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 0); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); + } - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOV(ir, IREG_temp0_W, IREG_16(fetchdat & 7)); - src_reg = IREG_temp0_W; - } - else - { - x86seg *target_seg; + return op_pc + 1; +} +uint32_t +ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - src_reg = IREG_temp0_W; - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_LOAD_SEG(ir, rseg, src_reg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); + } - return op_pc + 1; + return op_pc + 1; +} +uint32_t +ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); + } + + return op_pc + 1; +} +uint32_t +ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } + + return op_pc + 1; +} +uint32_t +ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } + + return op_pc + 1; +} +uint32_t +ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } + + return op_pc + 1; } -uint32_t ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVSX(ir, IREG_16(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVSX(ir, IREG_16(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + uop_MEM_LOAD_ABS(ir, IREG_AL, ireg_seg_base(op_ea_seg), addr); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVSX(ir, IREG_32(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + uop_MEM_LOAD_ABS(ir, IREG_AX, ireg_seg_base(op_ea_seg), addr); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr = 0; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVSX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + if (op_32 & 0x200) { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + op_pc); + } else { + addr = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); } - else - { - x86seg *target_seg; + } else { + addr = fastreadw(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 2); + } - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + if ((block->flags & CODEBLOCK_NO_IMMEDIATES) && (op_32 & 0x200)) + uop_MEM_LOAD_REG(ir, IREG_EAX, ireg_seg_base(op_ea_seg), IREG_eaaddr); + else + uop_MEM_LOAD_ABS(ir, IREG_EAX, ireg_seg_base(op_ea_seg), addr); - return op_pc + 1; + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_16(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_16(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AL); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AX); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_EAX); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } - -uint32_t ropXCHG_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg2 = IREG_16(opcode & 7); + x86seg *target_seg; + uint8_t imm; - uop_MOV(ir, IREG_temp0_W, IREG_AX); - uop_MOV(ir, IREG_AX, reg2); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + imm = fastreadb(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_8(dest_reg), imm); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadb(cs + op_pc + 1); + uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } + + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; +} +uint32_t +ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + uint16_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + imm = fastreadw(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_16(dest_reg), imm); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadw(cs + op_pc + 1); + uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } + + codegen_mark_code_present(block, cs + op_pc + 1, 2); + return op_pc + 3; +} +uint32_t +ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + uint32_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + imm = fastreadl(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_32(dest_reg), imm); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadl(cs + op_pc + 1); + uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } + + codegen_mark_code_present(block, cs + op_pc + 1, 4); + return op_pc + 5; +} + +uint32_t +ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg; + + codegen_mark_code_present(block, cs + op_pc, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + src_reg = IREG_ES_seg_W; + break; + case 0x08: /*CS*/ + src_reg = IREG_CS_seg_W; + break; + case 0x18: /*DS*/ + src_reg = IREG_DS_seg_W; + break; + case 0x10: /*SS*/ + src_reg = IREG_SS_seg_W; + break; + case 0x20: /*FS*/ + src_reg = IREG_FS_seg_W; + break; + case 0x28: /*GS*/ + src_reg = IREG_GS_seg_W; + break; + default: + return 0; + } + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), src_reg); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); + } + + return op_pc + 1; +} +uint32_t +ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg; + + codegen_mark_code_present(block, cs + op_pc, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + src_reg = IREG_ES_seg_W; + break; + case 0x08: /*CS*/ + src_reg = IREG_CS_seg_W; + break; + case 0x18: /*DS*/ + src_reg = IREG_DS_seg_W; + break; + case 0x10: /*SS*/ + src_reg = IREG_SS_seg_W; + break; + case 0x20: /*FS*/ + src_reg = IREG_FS_seg_W; + break; + case 0x28: /*GS*/ + src_reg = IREG_GS_seg_W; + break; + default: + return 0; + } + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), src_reg); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); + } + + return op_pc + 1; +} + +uint32_t +ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg; + x86seg *rseg; + + codegen_mark_code_present(block, cs + op_pc, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + rseg = &cpu_state.seg_es; + break; + case 0x18: /*DS*/ + rseg = &cpu_state.seg_ds; + break; + case 0x20: /*FS*/ + rseg = &cpu_state.seg_fs; + break; + case 0x28: /*GS*/ + rseg = &cpu_state.seg_gs; + break; + default: + return 0; + } + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_temp0_W, IREG_16(fetchdat & 7)); + src_reg = IREG_temp0_W; + } else { + x86seg *target_seg; + + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0_W; + } + + uop_LOAD_SEG(ir, rseg, src_reg); + + return op_pc + 1; +} + +uint32_t +ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_16(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_16(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_32(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_W); + } + + return op_pc + 1; +} + +uint32_t +ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_16(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_16(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_W); + } + + return op_pc + 1; +} + +uint32_t +ropXCHG_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg2 = IREG_16(opcode & 7); + + uop_MOV(ir, IREG_temp0_W, IREG_AX); + uop_MOV(ir, IREG_AX, reg2); + uop_MOV(ir, reg2, IREG_temp0_W); + + return op_pc; +} +uint32_t +ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg2 = IREG_32(opcode & 7); + + uop_MOV(ir, IREG_temp0, IREG_EAX); + uop_MOV(ir, IREG_EAX, reg2); + uop_MOV(ir, reg2, IREG_temp0); + + return op_pc; +} + +uint32_t +ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg1 = IREG_8((fetchdat >> 3) & 7); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int reg2 = IREG_8(fetchdat & 7); + + uop_MOV(ir, IREG_temp0_B, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0_B); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg1 = IREG_16((fetchdat >> 3) & 7); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int reg2 = IREG_16(fetchdat & 7); + + uop_MOV(ir, IREG_temp0_W, reg1); + uop_MOV(ir, reg1, reg2); uop_MOV(ir, reg2, IREG_temp0_W); + } else { + x86seg *target_seg; - return op_pc; -} -uint32_t ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int reg2 = IREG_32(opcode & 7); - - uop_MOV(ir, IREG_temp0, IREG_EAX); - uop_MOV(ir, IREG_EAX, reg2); - uop_MOV(ir, reg2, IREG_temp0); - - return op_pc; -} - -uint32_t ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int reg1 = IREG_8((fetchdat >> 3) & 7); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int reg2 = IREG_8(fetchdat & 7); - - uop_MOV(ir, IREG_temp0_B, reg1); - uop_MOV(ir, reg1, reg2); - uop_MOV(ir, reg2, IREG_temp0_B); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); - uop_MOV(ir, reg1, IREG_temp0_B); - } - - return op_pc + 1; -} -uint32_t ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int reg1 = IREG_16((fetchdat >> 3) & 7); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int reg2 = IREG_16(fetchdat & 7); - - uop_MOV(ir, IREG_temp0_W, reg1); - uop_MOV(ir, reg1, reg2); - uop_MOV(ir, reg2, IREG_temp0_W); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); - uop_MOV(ir, reg1, IREG_temp0_W); - } - - return op_pc + 1; -} -uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int reg1 = IREG_32((fetchdat >> 3) & 7); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int reg2 = IREG_32(fetchdat & 7); - - uop_MOV(ir, IREG_temp0, reg1); - uop_MOV(ir, reg1, reg2); - uop_MOV(ir, reg2, IREG_temp0); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); - uop_MOV(ir, reg1, IREG_temp0); - } - - return op_pc + 1; -} - -uint32_t ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MOVZX(ir, IREG_eaaddr, IREG_AL); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_EBX); - if (!(op_32 & 0x200)) - uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_AL, ireg_seg_base(op_ea_seg), IREG_eaaddr); - - return op_pc; + return op_pc + 1; +} +uint32_t +ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg1 = IREG_32((fetchdat >> 3) & 7); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int reg2 = IREG_32(fetchdat & 7); + + uop_MOV(ir, IREG_temp0, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0); + } + + return op_pc + 1; +} + +uint32_t +ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + uop_MOVZX(ir, IREG_eaaddr, IREG_AL); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_EBX); + if (!(op_32 & 0x200)) + uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + + uop_MEM_LOAD_REG(ir, IREG_AL, ireg_seg_base(op_ea_seg), IREG_eaaddr); + + return op_pc; } diff --git a/src/codegen_new/codegen_ops_shift.c b/src/codegen_new/codegen_ops_shift.c index 370585bf2..8ccf7d9e7 100644 --- a/src/codegen_new/codegen_ops_shift.c +++ b/src/codegen_new/codegen_ops_shift.c @@ -13,1126 +13,1097 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_shift.h" -static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) +static uint32_t +shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) { - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x20: case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SAR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SAR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - default: - return 0; - } - } - else - { - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x28: /*SHR*/ - uop_SHR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x38: /*SAR*/ - uop_SAR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} - -static uint32_t shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SAR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - default: - return 0; - } - } - else - { - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x28: /*SHR*/ - uop_SHR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x38: /*SAR*/ - uop_SAR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SAR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - default: - return 0; - } - } - else - { - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_temp0, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_temp0, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x28: /*SHR*/ - uop_SHR_IMM(ir, IREG_temp1, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x38: /*SAR*/ - uop_SAR_IMM(ir, IREG_temp1, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} - -static uint32_t shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count_reg) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - default: - return 0; - } - } - else - { - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - uint8_t imm; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + default: return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; - if (imm) - return shift_common_8(ir, fetchdat, op_pc, target_seg, imm) + 1; - return op_pc+1; -} -uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - uint8_t imm; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + case 0x20: + case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + default: return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); + } - if (imm) - return shift_common_16(ir, fetchdat, op_pc, target_seg, imm) + 1; - return op_pc+1; -} -uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - } - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uint32_t new_pc; - int jump_uop; - - LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp2, cs + op_pc + 1); - uop_AND_IMM(ir, IREG_temp2, IREG_temp2, 0x1f); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp2, 0); - - new_pc = shift_common_variable_32(ir, fetchdat, op_pc, target_seg, IREG_temp2) + 1; - uop_NOP_BARRIER(ir); - uop_set_jump_dest(ir, jump_uop); - return new_pc; - } - else - { - uint8_t imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); - - if (imm) - return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1; - } - return op_pc+1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static uint32_t +shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) { - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - } - - return shift_common_8(ir, fetchdat, op_pc, target_seg, 1); -} -uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - } - - return shift_common_16(ir, fetchdat, op_pc, target_seg, 1); -} -uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - } - - return shift_common_32(ir, fetchdat, op_pc, target_seg, 1); -} - -uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - if (!(CL & 0x1f) || !block->ins) - return 0; - - uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SAR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - if (!(CL & 0x1f) || !block->ins) - return 0; - - uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SAR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - if (!(CL & 0x1f) || !block->ins) - return 0; - - uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); - - if (!imm) - return op_pc+2; - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHL_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); - uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); - - uop_SHL_IMM(ir, IREG_temp0_W, IREG_temp2, imm); - uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - - uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - } - - return op_pc+2; -} -uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); - - if (!imm) - return op_pc+2; - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); - uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); - - uop_SHL_IMM(ir, IREG_temp0, IREG_temp2, imm); - uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - - uop_MOV(ir, IREG_flags_op1, IREG_temp2); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - } - - return op_pc+2; -} -uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); - - if (!imm) - return op_pc+2; - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + break; + case 0x28: /*SHR*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHR_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); - uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SHR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + break; - uop_SHR_IMM(ir, IREG_temp0_W, IREG_temp2, imm); - uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SAR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - - uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - } + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - return op_pc+2; + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static uint32_t +shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) { - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - if (!imm) - return op_pc+2; - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + case 0x20: + case 0x30: /*SHL*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); - uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + break; - uop_SHR_IMM(ir, IREG_temp0, IREG_temp2, imm); - uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0, IREG_temp0, count); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - - uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - } + break; - return op_pc+2; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} + +static uint32_t +shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count_reg) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t +ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint8_t imm; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (imm) + return shift_common_8(ir, fetchdat, op_pc, target_seg, imm) + 1; + return op_pc + 1; +} +uint32_t +ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint8_t imm; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (imm) + return shift_common_16(ir, fetchdat, op_pc, target_seg, imm) + 1; + return op_pc + 1; +} +uint32_t +ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uint32_t new_pc; + int jump_uop; + + LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp2, cs + op_pc + 1); + uop_AND_IMM(ir, IREG_temp2, IREG_temp2, 0x1f); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp2, 0); + + new_pc = shift_common_variable_32(ir, fetchdat, op_pc, target_seg, IREG_temp2) + 1; + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + return new_pc; + } else { + uint8_t imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (imm) + return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1; + } + return op_pc + 1; +} + +uint32_t +ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + } + + return shift_common_8(ir, fetchdat, op_pc, target_seg, 1); +} +uint32_t +ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + } + + return shift_common_16(ir, fetchdat, op_pc, target_seg, 1); +} +uint32_t +ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + } + + return shift_common_32(ir, fetchdat, op_pc, target_seg, 1); +} + +uint32_t +ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + if (!(CL & 0x1f) || !block->ins) + return 0; + + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SAR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + default: + return 0; + } + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + if (!(CL & 0x1f) || !block->ins) + return 0; + + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SAR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + default: + return 0; + } + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + if (!(CL & 0x1f) || !block->ins) + return 0; + + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + default: + return 0; + } + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t +ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (!imm) + return op_pc + 2; + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); + uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHL_IMM(ir, IREG_temp0_W, IREG_temp2, imm); + uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + + uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + } + + return op_pc + 2; +} +uint32_t +ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (!imm) + return op_pc + 2; + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); + uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHL_IMM(ir, IREG_temp0, IREG_temp2, imm); + uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + + uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + } + + return op_pc + 2; +} +uint32_t +ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (!imm) + return op_pc + 2; + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); + uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHR_IMM(ir, IREG_temp0_W, IREG_temp2, imm); + uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + + uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + } + + return op_pc + 2; +} +uint32_t +ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (!imm) + return op_pc + 2; + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); + uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHR_IMM(ir, IREG_temp0, IREG_temp2, imm); + uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + + uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + } + + return op_pc + 2; } diff --git a/src/codegen_new/codegen_ops_stack.c b/src/codegen_new/codegen_ops_stack.c index ff421488e..b7afdce25 100644 --- a/src/codegen_new/codegen_ops_stack.c +++ b/src/codegen_new/codegen_ops_stack.c @@ -12,248 +12,243 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_misc.h" -uint32_t ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_16(opcode & 7)); - SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_16(opcode & 7)); + SUB_SP(ir, 2); - return op_pc; + return op_pc; } -uint32_t ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_32(opcode & 7)); - SUB_SP(ir, 4); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_32(opcode & 7)); + SUB_SP(ir, 4); - return op_pc; + return op_pc; } -uint32_t ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_eaaddr); + } + if ((opcode & 7) != REG_SP) + ADD_SP(ir, 2); + + return op_pc; +} +uint32_t +ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_eaaddr); + } + if ((opcode & 7) != REG_ESP) + ADD_SP(ir, 4); + + return op_pc; +} + +uint32_t +ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm = fastreadw(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 2); + + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; +} +uint32_t +ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t imm = fastreadl(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 4); + + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; +} + +uint32_t +ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm = (int16_t) (int8_t) fastreadb(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 2); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} +uint32_t +ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t imm = (int32_t) (int8_t) fastreadb(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 4); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} + +uint32_t +ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_eaaddr); + } + } else { + x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 2); + codegen_check_seg_write(block, ir, target_seg); if (stack32) - uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_temp0, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_temp0); } - if ((opcode & 7) != REG_SP) - ADD_SP(ir, 2); - return op_pc; + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + } + + if ((fetchdat & 0xc7) != (0xc0 | REG_SP)) + ADD_SP(ir, 2); + + return op_pc + 1; } -uint32_t ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_eaaddr); + } + } else { + x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 4); + codegen_check_seg_write(block, ir, target_seg); if (stack32) - uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_eaaddr); - } - if ((opcode & 7) != REG_ESP) - ADD_SP(ir, 4); - - return op_pc; -} - -uint32_t ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint16_t imm = fastreadw(cs + op_pc); - int sp_reg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 2); - - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; -} -uint32_t ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t imm = fastreadl(cs + op_pc); - int sp_reg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 4); - - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; -} - -uint32_t ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc); - int sp_reg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 2); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; -} -uint32_t ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc); - int sp_reg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 4); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; -} - -uint32_t ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_eaaddr); - } - } - else - { - x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 2); - codegen_check_seg_write(block, ir, target_seg); - - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_temp0, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_temp0); - } - - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_temp0, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_temp0); } - if ((fetchdat & 0xc7) != (0xc0 | REG_SP)) - ADD_SP(ir, 2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + } - return op_pc + 1; -} -uint32_t ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + if ((fetchdat & 0xc7) != (0xc0 | REG_ESP)) + ADD_SP(ir, 4); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_eaaddr); - } - } - else - { - x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 4); - codegen_check_seg_write(block, ir, target_seg); - - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_temp0, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_temp0); - } - - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - } - - if ((fetchdat & 0xc7) != (0xc0 | REG_ESP)) - ADD_SP(ir, 4); - - return op_pc + 1; + return op_pc + 1; } -#define ROP_PUSH_SEG(seg) \ -uint32_t ropPUSH_ ## seg ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int sp_reg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \ - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_ ## seg ## _seg_W); \ - SUB_SP(ir, 2); \ - \ - return op_pc; \ -} \ -uint32_t ropPUSH_ ## seg ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int sp_reg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \ - uop_MOVZX(ir, IREG_temp0, IREG_ ## seg ## _seg_W); \ - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \ - SUB_SP(ir, 4); \ - \ - return op_pc; \ -} - -#define ROP_POP_SEG(seg, rseg) \ -uint32_t ropPOP_ ## seg ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - \ - if (stack32) \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ - else \ - { \ - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ - } \ - uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ - ADD_SP(ir, 2); \ - \ - return op_pc; \ -} \ -uint32_t ropPOP_ ## seg ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - \ - if (stack32) \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ - else \ - { \ - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ - } \ - uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ - ADD_SP(ir, 4); \ - \ - return op_pc; \ -} +#define ROP_PUSH_SEG(seg) \ + uint32_t ropPUSH_##seg##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_##seg##_seg_W); \ + SUB_SP(ir, 2); \ + \ + return op_pc; \ + } \ + uint32_t ropPUSH_##seg##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \ + uop_MOVZX(ir, IREG_temp0, IREG_##seg##_seg_W); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \ + SUB_SP(ir, 4); \ + \ + return op_pc; \ + } +#define ROP_POP_SEG(seg, rseg) \ + uint32_t ropPOP_##seg##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 2); \ + \ + return op_pc; \ + } \ + uint32_t ropPOP_##seg##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 4); \ + \ + return op_pc; \ + } ROP_PUSH_SEG(CS) ROP_PUSH_SEG(DS) @@ -266,147 +261,152 @@ ROP_POP_SEG(ES, cpu_state.seg_es) ROP_POP_SEG(FS, cpu_state.seg_fs) ROP_POP_SEG(GS, cpu_state.seg_gs) -uint32_t ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_EBP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_BP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - } - uop_ADD_IMM(ir, IREG_SP, IREG_BP, 2); - uop_MOV(ir, IREG_BP, IREG_temp0_W); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_EBP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_BP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + uop_ADD_IMM(ir, IREG_SP, IREG_BP, 2); + uop_MOV(ir, IREG_BP, IREG_temp0_W); - return op_pc; + return op_pc; } -uint32_t ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_EBP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_BP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); - } - uop_ADD_IMM(ir, IREG_ESP, IREG_EBP, 4); - uop_MOV(ir, IREG_EBP, IREG_temp0); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_EBP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_BP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + } + uop_ADD_IMM(ir, IREG_ESP, IREG_EBP, 4); + uop_MOV(ir, IREG_EBP, IREG_temp0); - return op_pc; + return op_pc; } - -uint32_t ropPUSHA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSHA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -16); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 14, IREG_AX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_CX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 10, IREG_DX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_BX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 6, IREG_SP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_BP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_SI); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_DI); - SUB_SP(ir, 16); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -16); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 14, IREG_AX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_CX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 10, IREG_DX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_BX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 6, IREG_SP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_BP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_SI); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_DI); + SUB_SP(ir, 16); - return op_pc; + return op_pc; } -uint32_t ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -32); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 28, IREG_EAX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 24, IREG_ECX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 20, IREG_EDX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 16, IREG_EBX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_ESP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_EBP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_ESI); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_EDI); - SUB_SP(ir, 32); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -32); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 28, IREG_EAX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 24, IREG_ECX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 20, IREG_EDX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 16, IREG_EBX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_ESP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_EBP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_ESI); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_EDI); + SUB_SP(ir, 32); - return op_pc; + return op_pc; } -uint32_t ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP(ir); - uop_MEM_LOAD_REG(ir, IREG_DI, IREG_SS_base, sp_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_SI, IREG_SS_base, sp_reg, 2); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_BP, IREG_SS_base, sp_reg, 4); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_BX, IREG_SS_base, sp_reg, 8); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_DX, IREG_SS_base, sp_reg, 10); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_CX, IREG_SS_base, sp_reg, 12); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_AX, IREG_SS_base, sp_reg, 14); - ADD_SP(ir, 16); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP(ir); + uop_MEM_LOAD_REG(ir, IREG_DI, IREG_SS_base, sp_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_SI, IREG_SS_base, sp_reg, 2); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_BP, IREG_SS_base, sp_reg, 4); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_BX, IREG_SS_base, sp_reg, 8); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_DX, IREG_SS_base, sp_reg, 10); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_CX, IREG_SS_base, sp_reg, 12); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_AX, IREG_SS_base, sp_reg, 14); + ADD_SP(ir, 16); - return op_pc; + return op_pc; } -uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP(ir); - uop_MEM_LOAD_REG(ir, IREG_EDI, IREG_SS_base, sp_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_ESI, IREG_SS_base, sp_reg, 4); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBP, IREG_SS_base, sp_reg, 8); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBX, IREG_SS_base, sp_reg, 16); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EDX, IREG_SS_base, sp_reg, 20); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_ECX, IREG_SS_base, sp_reg, 24); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EAX, IREG_SS_base, sp_reg, 28); - ADD_SP(ir, 32); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP(ir); + uop_MEM_LOAD_REG(ir, IREG_EDI, IREG_SS_base, sp_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_ESI, IREG_SS_base, sp_reg, 4); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBP, IREG_SS_base, sp_reg, 8); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBX, IREG_SS_base, sp_reg, 16); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EDX, IREG_SS_base, sp_reg, 20); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_ECX, IREG_SS_base, sp_reg, 24); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EAX, IREG_SS_base, sp_reg, 28); + ADD_SP(ir, 32); - return op_pc; + return op_pc; } -uint32_t ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - return 0; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_CALL_FUNC(ir, flags_rebuild); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); - SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + SUB_SP(ir, 2); - return op_pc; + return op_pc; } -uint32_t ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - return 0; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_CALL_FUNC(ir, flags_rebuild); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); - if (cpu_CR4_mask & CR4_VME) - uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c); - else if (CPUID) - uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x24); - else - uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 4); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_temp0_W); - SUB_SP(ir, 4); + if (cpu_CR4_mask & CR4_VME) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c); + else if (CPUID) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x24); + else + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 4); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_temp0_W); + SUB_SP(ir, 4); - return op_pc; + return op_pc; } diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index 6b0cc0fd3..7cd7b418a 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -8,916 +8,879 @@ #include "codegen_ir_defs.h" #include "codegen_reg.h" -int max_version_refcount; +int max_version_refcount; uint16_t reg_dead_list = 0; -uint8_t reg_last_version[IREG_COUNT]; +uint8_t reg_last_version[IREG_COUNT]; reg_version_t reg_version[IREG_COUNT][256]; -ir_reg_t invalid_ir_reg = {IREG_INVALID}; +ir_reg_t invalid_ir_reg = { IREG_INVALID }; -ir_reg_t _host_regs[CODEGEN_HOST_REGS]; +ir_reg_t _host_regs[CODEGEN_HOST_REGS]; static uint8_t _host_reg_dirty[CODEGEN_HOST_REGS]; -ir_reg_t host_fp_regs[CODEGEN_HOST_FP_REGS]; +ir_reg_t host_fp_regs[CODEGEN_HOST_FP_REGS]; static uint8_t host_fp_reg_dirty[CODEGEN_HOST_FP_REGS]; -typedef struct host_reg_set_t -{ - ir_reg_t *regs; - uint8_t *dirty; - host_reg_def_t *reg_list; - uint16_t locked; - int nr_regs; +typedef struct host_reg_set_t { + ir_reg_t *regs; + uint8_t *dirty; + host_reg_def_t *reg_list; + uint16_t locked; + int nr_regs; } host_reg_set_t; static host_reg_set_t host_reg_set, host_fp_reg_set; -enum -{ - REG_BYTE, - REG_WORD, - REG_DWORD, - REG_QWORD, - REG_POINTER, - REG_DOUBLE, - REG_FPU_ST_BYTE, - REG_FPU_ST_DOUBLE, - REG_FPU_ST_QWORD +enum { + REG_BYTE, + REG_WORD, + REG_DWORD, + REG_QWORD, + REG_POINTER, + REG_DOUBLE, + REG_FPU_ST_BYTE, + REG_FPU_ST_DOUBLE, + REG_FPU_ST_QWORD }; -enum -{ - REG_INTEGER, - REG_FP +enum { + REG_INTEGER, + REG_FP }; -enum -{ - /*Register may be accessed outside of code block, and must be written - back before any control transfers*/ - REG_PERMANENT = 0, - /*Register will not be accessed outside of code block, and does not need - to be written back if there are no readers remaining*/ - REG_VOLATILE = 1 +enum { + /*Register may be accessed outside of code block, and must be written + back before any control transfers*/ + REG_PERMANENT = 0, + /*Register will not be accessed outside of code block, and does not need + to be written back if there are no readers remaining*/ + REG_VOLATILE = 1 }; struct { - int native_size; - void *p; - int type; - int is_volatile; -} ireg_data[IREG_COUNT] = -{ - [IREG_EAX] = {REG_DWORD, &EAX, REG_INTEGER, REG_PERMANENT}, - [IREG_ECX] = {REG_DWORD, &ECX, REG_INTEGER, REG_PERMANENT}, - [IREG_EDX] = {REG_DWORD, &EDX, REG_INTEGER, REG_PERMANENT}, - [IREG_EBX] = {REG_DWORD, &EBX, REG_INTEGER, REG_PERMANENT}, - [IREG_ESP] = {REG_DWORD, &ESP, REG_INTEGER, REG_PERMANENT}, - [IREG_EBP] = {REG_DWORD, &EBP, REG_INTEGER, REG_PERMANENT}, - [IREG_ESI] = {REG_DWORD, &ESI, REG_INTEGER, REG_PERMANENT}, - [IREG_EDI] = {REG_DWORD, &EDI, REG_INTEGER, REG_PERMANENT}, + int native_size; + void *p; + int type; + int is_volatile; +} ireg_data[IREG_COUNT] = { + [IREG_EAX] = {REG_DWORD, &EAX, REG_INTEGER, REG_PERMANENT}, + [IREG_ECX] = { REG_DWORD, &ECX, REG_INTEGER, REG_PERMANENT}, + [IREG_EDX] = { REG_DWORD, &EDX, REG_INTEGER, REG_PERMANENT}, + [IREG_EBX] = { REG_DWORD, &EBX, REG_INTEGER, REG_PERMANENT}, + [IREG_ESP] = { REG_DWORD, &ESP, REG_INTEGER, REG_PERMANENT}, + [IREG_EBP] = { REG_DWORD, &EBP, REG_INTEGER, REG_PERMANENT}, + [IREG_ESI] = { REG_DWORD, &ESI, REG_INTEGER, REG_PERMANENT}, + [IREG_EDI] = { REG_DWORD, &EDI, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op] = {REG_DWORD, &cpu_state.flags_op, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_res] = {REG_DWORD, &cpu_state.flags_res, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op1] = {REG_DWORD, &cpu_state.flags_op1, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op2] = {REG_DWORD, &cpu_state.flags_op2, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op] = { REG_DWORD, &cpu_state.flags_op, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_res] = { REG_DWORD, &cpu_state.flags_res, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op1] = { REG_DWORD, &cpu_state.flags_op1, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op2] = { REG_DWORD, &cpu_state.flags_op2, REG_INTEGER, REG_PERMANENT}, - [IREG_pc] = {REG_DWORD, &cpu_state.pc, REG_INTEGER, REG_PERMANENT}, - [IREG_oldpc] = {REG_DWORD, &cpu_state.oldpc, REG_INTEGER, REG_PERMANENT}, + [IREG_pc] = { REG_DWORD, &cpu_state.pc, REG_INTEGER, REG_PERMANENT}, + [IREG_oldpc] = { REG_DWORD, &cpu_state.oldpc, REG_INTEGER, REG_PERMANENT}, - [IREG_eaaddr] = {REG_DWORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT}, - [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg, REG_INTEGER, REG_PERMANENT}, + [IREG_eaaddr] = { REG_DWORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT}, + [IREG_ea_seg] = { REG_POINTER, &cpu_state.ea_seg, REG_INTEGER, REG_PERMANENT}, - [IREG_op32] = {REG_DWORD, &cpu_state.op32, REG_INTEGER, REG_PERMANENT}, - [IREG_ssegsx] = {REG_BYTE, &cpu_state.ssegs, REG_INTEGER, REG_PERMANENT}, + [IREG_op32] = { REG_DWORD, &cpu_state.op32, REG_INTEGER, REG_PERMANENT}, + [IREG_ssegsx] = { REG_BYTE, &cpu_state.ssegs, REG_INTEGER, REG_PERMANENT}, - [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER, REG_PERMANENT}, + [IREG_rm_mod_reg] = { REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER, REG_PERMANENT}, #ifdef USE_ACYCS - [IREG_acycs] = {REG_DWORD, &acycs, REG_INTEGER, REG_PERMANENT}, + [IREG_acycs] = { REG_DWORD, &acycs, REG_INTEGER, REG_PERMANENT}, #endif - [IREG_cycles] = {REG_DWORD, &cpu_state._cycles, REG_INTEGER, REG_PERMANENT}, + [IREG_cycles] = { REG_DWORD, &cpu_state._cycles, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_base] = {REG_DWORD, &cpu_state.seg_ds.base, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_base] = {REG_DWORD, &cpu_state.seg_es.base, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_base] = {REG_DWORD, &cpu_state.seg_fs.base, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_base] = { REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_base] = { REG_DWORD, &cpu_state.seg_ds.base, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_base] = { REG_DWORD, &cpu_state.seg_es.base, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_base] = { REG_DWORD, &cpu_state.seg_fs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_base] = { REG_DWORD, &cpu_state.seg_gs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_base] = { REG_DWORD, &cpu_state.seg_ss.base, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_seg] = { REG_WORD, &cpu_state.seg_cs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_seg] = { REG_WORD, &cpu_state.seg_ds.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_seg] = { REG_WORD, &cpu_state.seg_es.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_seg] = { REG_WORD, &cpu_state.seg_fs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_seg] = { REG_WORD, &cpu_state.seg_gs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_seg] = { REG_WORD, &cpu_state.seg_ss.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_FPU_TOP] = {REG_DWORD, &cpu_state.TOP, REG_INTEGER, REG_PERMANENT}, + [IREG_FPU_TOP] = { REG_DWORD, &cpu_state.TOP, REG_INTEGER, REG_PERMANENT}, - [IREG_ST0] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST1] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST2] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST3] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST4] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST5] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST6] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST7] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST0] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST1] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST2] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST3] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST4] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST5] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST6] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST7] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_tag0] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag1] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag2] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag3] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag4] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag5] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag0] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag1] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag2] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag3] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag4] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag5] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag6] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag7] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_ST0_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST1_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST2_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST3_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST4_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST5_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST6_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST7_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST0_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST1_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST2_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST3_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST4_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST5_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST6_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST7_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_MM0x] = {REG_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_MM1x] = {REG_QWORD, &cpu_state.MM[1], REG_FP, REG_PERMANENT}, - [IREG_MM2x] = {REG_QWORD, &cpu_state.MM[2], REG_FP, REG_PERMANENT}, - [IREG_MM3x] = {REG_QWORD, &cpu_state.MM[3], REG_FP, REG_PERMANENT}, - [IREG_MM4x] = {REG_QWORD, &cpu_state.MM[4], REG_FP, REG_PERMANENT}, - [IREG_MM5x] = {REG_QWORD, &cpu_state.MM[5], REG_FP, REG_PERMANENT}, - [IREG_MM6x] = {REG_QWORD, &cpu_state.MM[6], REG_FP, REG_PERMANENT}, - [IREG_MM7x] = {REG_QWORD, &cpu_state.MM[7], REG_FP, REG_PERMANENT}, + [IREG_MM0x] = { REG_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_MM1x] = { REG_QWORD, &cpu_state.MM[1], REG_FP, REG_PERMANENT}, + [IREG_MM2x] = { REG_QWORD, &cpu_state.MM[2], REG_FP, REG_PERMANENT}, + [IREG_MM3x] = { REG_QWORD, &cpu_state.MM[3], REG_FP, REG_PERMANENT}, + [IREG_MM4x] = { REG_QWORD, &cpu_state.MM[4], REG_FP, REG_PERMANENT}, + [IREG_MM5x] = { REG_QWORD, &cpu_state.MM[5], REG_FP, REG_PERMANENT}, + [IREG_MM6x] = { REG_QWORD, &cpu_state.MM[6], REG_FP, REG_PERMANENT}, + [IREG_MM7x] = { REG_QWORD, &cpu_state.MM[7], REG_FP, REG_PERMANENT}, - [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER, REG_PERMANENT}, - [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER, REG_PERMANENT}, + [IREG_NPXCx] = { REG_WORD, &cpu_state.npxc, REG_INTEGER, REG_PERMANENT}, + [IREG_NPXSx] = { REG_WORD, &cpu_state.npxs, REG_INTEGER, REG_PERMANENT}, - [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT}, - [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT}, + [IREG_flagsx] = { REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT}, + [IREG_eflagsx] = { REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_limit_low] = {REG_DWORD, &cpu_state.seg_cs.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_limit_low] = {REG_DWORD, &cpu_state.seg_ds.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_limit_low] = {REG_DWORD, &cpu_state.seg_es.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_limit_low] = {REG_DWORD, &cpu_state.seg_fs.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_limit_low] = {REG_DWORD, &cpu_state.seg_gs.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_limit_low] = {REG_DWORD, &cpu_state.seg_ss.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_limit_low] = { REG_DWORD, &cpu_state.seg_cs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_limit_low] = { REG_DWORD, &cpu_state.seg_ds.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_limit_low] = { REG_DWORD, &cpu_state.seg_es.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_limit_low] = { REG_DWORD, &cpu_state.seg_fs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_limit_low] = { REG_DWORD, &cpu_state.seg_gs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_limit_low] = { REG_DWORD, &cpu_state.seg_ss.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_limit_high] = {REG_DWORD, &cpu_state.seg_cs.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_limit_high] = {REG_DWORD, &cpu_state.seg_ds.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_limit_high] = {REG_DWORD, &cpu_state.seg_es.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_limit_high] = {REG_DWORD, &cpu_state.seg_fs.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_limit_high] = {REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_limit_high] = {REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_limit_high] = { REG_DWORD, &cpu_state.seg_cs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_limit_high] = { REG_DWORD, &cpu_state.seg_ds.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_limit_high] = { REG_DWORD, &cpu_state.seg_es.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_limit_high] = { REG_DWORD, &cpu_state.seg_fs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_limit_high] = { REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_limit_high] = { REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT}, - /*Temporary registers are stored on the stack, and are not guaranteed to - be preserved across uOPs. They will not be written back if they will - not be read again.*/ - [IREG_temp0] = {REG_DWORD, (void *)16, REG_INTEGER, REG_VOLATILE}, - [IREG_temp1] = {REG_DWORD, (void *)20, REG_INTEGER, REG_VOLATILE}, - [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER, REG_VOLATILE}, - [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER, REG_VOLATILE}, + /*Temporary registers are stored on the stack, and are not guaranteed to + be preserved across uOPs. They will not be written back if they will + not be read again.*/ + [IREG_temp0] = { REG_DWORD, (void *) 16, REG_INTEGER, REG_VOLATILE }, + [IREG_temp1] = { REG_DWORD, (void *) 20, REG_INTEGER, REG_VOLATILE }, + [IREG_temp2] = { REG_DWORD, (void *) 24, REG_INTEGER, REG_VOLATILE }, + [IREG_temp3] = { REG_DWORD, (void *) 28, REG_INTEGER, REG_VOLATILE }, - [IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP, REG_VOLATILE}, - [IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP, REG_VOLATILE}, + [IREG_temp0d] = { REG_DOUBLE, (void *) 40, REG_FP, REG_VOLATILE }, + [IREG_temp1d] = { REG_DOUBLE, (void *) 48, REG_FP, REG_VOLATILE }, }; -void codegen_reg_mark_as_required() +void +codegen_reg_mark_as_required(void) { - int reg; + int reg; - for (reg = 0; reg < IREG_COUNT; reg++) - { - int last_version = reg_last_version[reg]; + for (reg = 0; reg < IREG_COUNT; reg++) { + int last_version = reg_last_version[reg]; - if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT) - reg_version[reg][last_version].flags |= REG_FLAGS_REQUIRED; - } + if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT) + reg_version[reg][last_version].flags |= REG_FLAGS_REQUIRED; + } } -int reg_is_native_size(ir_reg_t ir_reg) +int +reg_is_native_size(ir_reg_t ir_reg) { - int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; - int requested_size = IREG_GET_SIZE(ir_reg.reg); + int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; + int requested_size = IREG_GET_SIZE(ir_reg.reg); - switch (native_size) - { - case REG_BYTE: case REG_FPU_ST_BYTE: - return (requested_size == IREG_SIZE_B); - case REG_WORD: - return (requested_size == IREG_SIZE_W); - case REG_DWORD: + switch (native_size) { + case REG_BYTE: + case REG_FPU_ST_BYTE: + return (requested_size == IREG_SIZE_B); + case REG_WORD: + return (requested_size == IREG_SIZE_W); + case REG_DWORD: + return (requested_size == IREG_SIZE_L); + case REG_QWORD: + case REG_FPU_ST_QWORD: + case REG_DOUBLE: + case REG_FPU_ST_DOUBLE: + return ((requested_size == IREG_SIZE_D) || (requested_size == IREG_SIZE_Q)); + case REG_POINTER: + if (sizeof(void *) == 4) return (requested_size == IREG_SIZE_L); - case REG_QWORD: case REG_FPU_ST_QWORD: case REG_DOUBLE: case REG_FPU_ST_DOUBLE: - return ((requested_size == IREG_SIZE_D) || (requested_size == IREG_SIZE_Q)); - case REG_POINTER: - if (sizeof(void *) == 4) - return (requested_size == IREG_SIZE_L); - return (requested_size == IREG_SIZE_Q); + return (requested_size == IREG_SIZE_Q); - default: - fatal("get_reg_is_native_size: unknown native size %i\n", native_size); - } + default: + fatal("get_reg_is_native_size: unknown native size %i\n", native_size); + } - return 0; + return 0; } -void codegen_reg_reset() +void +codegen_reg_reset(void) { - int c; + int c; - host_reg_set.regs = _host_regs; - host_reg_set.dirty = _host_reg_dirty; - host_reg_set.reg_list = codegen_host_reg_list; - host_reg_set.locked = 0; - host_reg_set.nr_regs = CODEGEN_HOST_REGS; - host_fp_reg_set.regs = host_fp_regs; - host_fp_reg_set.dirty = host_fp_reg_dirty; - host_fp_reg_set.reg_list = codegen_host_fp_reg_list; - host_fp_reg_set.locked = 0; - host_fp_reg_set.nr_regs = CODEGEN_HOST_FP_REGS; + host_reg_set.regs = _host_regs; + host_reg_set.dirty = _host_reg_dirty; + host_reg_set.reg_list = codegen_host_reg_list; + host_reg_set.locked = 0; + host_reg_set.nr_regs = CODEGEN_HOST_REGS; + host_fp_reg_set.regs = host_fp_regs; + host_fp_reg_set.dirty = host_fp_reg_dirty; + host_fp_reg_set.reg_list = codegen_host_fp_reg_list; + host_fp_reg_set.locked = 0; + host_fp_reg_set.nr_regs = CODEGEN_HOST_FP_REGS; - for (c = 0; c < IREG_COUNT; c++) - { - reg_last_version[c] = 0; - reg_version[c][0].refcount = 0; - } - for (c = 0; c < CODEGEN_HOST_REGS; c++) - { - host_reg_set.regs[c] = invalid_ir_reg; - host_reg_set.dirty[c] = 0; - } - for (c = 0; c < CODEGEN_HOST_FP_REGS; c++) - { - host_fp_reg_set.regs[c] = invalid_ir_reg; - host_fp_reg_set.dirty[c] = 0; - } + for (c = 0; c < IREG_COUNT; c++) { + reg_last_version[c] = 0; + reg_version[c][0].refcount = 0; + } + for (c = 0; c < CODEGEN_HOST_REGS; c++) { + host_reg_set.regs[c] = invalid_ir_reg; + host_reg_set.dirty[c] = 0; + } + for (c = 0; c < CODEGEN_HOST_FP_REGS; c++) { + host_fp_reg_set.regs[c] = invalid_ir_reg; + host_fp_reg_set.dirty[c] = 0; + } - reg_dead_list = 0; - max_version_refcount = 0; + reg_dead_list = 0; + max_version_refcount = 0; } -static inline int ir_get_refcount(ir_reg_t ir_reg) +static inline int +ir_get_refcount(ir_reg_t ir_reg) { - return reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version].refcount; + return reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version].refcount; } -static inline host_reg_set_t *get_reg_set(ir_reg_t ir_reg) +static inline host_reg_set_t * +get_reg_set(ir_reg_t ir_reg) { - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type == REG_INTEGER) - return &host_reg_set; - else - return &host_fp_reg_set; + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type == REG_INTEGER) + return &host_reg_set; + else + return &host_fp_reg_set; } -static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, ir_reg_t ir_reg) +static void +codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, ir_reg_t ir_reg) { - switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) - { - case REG_WORD: + switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) { + case REG_WORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_16(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_16(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_DWORD: + case REG_DWORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_32(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_32(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_QWORD: + case REG_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_64(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_64(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_POINTER: + case REG_POINTER: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_pointer(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_pointer(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_DOUBLE: + case REG_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_double(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_double(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_FPU_ST_BYTE: + case REG_FPU_ST_BYTE: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]); - else - codegen_direct_read_st_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[0], ir_reg.reg & 7); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]); + else + codegen_direct_read_st_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[0], ir_reg.reg & 7); + break; - case REG_FPU_ST_QWORD: + case REG_FPU_ST_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]); - else - codegen_direct_read_st_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[0], ir_reg.reg & 7); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]); + else + codegen_direct_read_st_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[0], ir_reg.reg & 7); + break; - case REG_FPU_ST_DOUBLE: + case REG_FPU_ST_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]); - else - codegen_direct_read_st_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[0], ir_reg.reg & 7); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]); + else + codegen_direct_read_st_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[0], ir_reg.reg & 7); + break; - default: - fatal("codegen_reg_load - native_size=%i reg=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size, IREG_GET_REG(ir_reg.reg)); - } + default: + fatal("codegen_reg_load - native_size=%i reg=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size, IREG_GET_REG(ir_reg.reg)); + } - reg_set->regs[c] = ir_reg; + reg_set->regs[c] = ir_reg; } -static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, int c, int invalidate) +static void +codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, int c, int invalidate) { - int ir_reg = IREG_GET_REG(reg_set->regs[c].reg); - void *p = ireg_data[ir_reg].p; + int ir_reg = IREG_GET_REG(reg_set->regs[c].reg); + void *p = ireg_data[ir_reg].p; - if (!reg_version[ir_reg][reg_set->regs[c].version].refcount && - ireg_data[ir_reg].is_volatile) - return; + if (!reg_version[ir_reg][reg_set->regs[c].version].refcount && ireg_data[ir_reg].is_volatile) + return; - switch (ireg_data[ir_reg].native_size) - { - case REG_BYTE: + switch (ireg_data[ir_reg].native_size) { + case REG_BYTE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); - if ((uintptr_t)p < 256) - fatal("codegen_reg_writeback - REG_BYTE %p\n", p); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); + if ((uintptr_t) p < 256) + fatal("codegen_reg_writeback - REG_BYTE %p\n", p); #endif - codegen_direct_write_8(block, p, reg_set->reg_list[c].reg); - break; + codegen_direct_write_8(block, p, reg_set->reg_list[c].reg); + break; - case REG_WORD: + case REG_WORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); - if ((uintptr_t)p < 256) - fatal("codegen_reg_writeback - REG_WORD %p\n", p); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); + if ((uintptr_t) p < 256) + fatal("codegen_reg_writeback - REG_WORD %p\n", p); #endif - codegen_direct_write_16(block, p, reg_set->reg_list[c].reg); - break; + codegen_direct_write_16(block, p, reg_set->reg_list[c].reg); + break; - case REG_DWORD: + case REG_DWORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); #endif - if ((uintptr_t)p < 256) - codegen_direct_write_32_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); - else - codegen_direct_write_32(block, p, reg_set->reg_list[c].reg); - break; + if ((uintptr_t) p < 256) + codegen_direct_write_32_stack(block, (intptr_t) p, reg_set->reg_list[c].reg); + else + codegen_direct_write_32(block, p, reg_set->reg_list[c].reg); + break; - case REG_QWORD: + case REG_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); #endif - if ((uintptr_t)p < 256) - codegen_direct_write_64_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); - else - codegen_direct_write_64(block, p, reg_set->reg_list[c].reg); - break; + if ((uintptr_t) p < 256) + codegen_direct_write_64_stack(block, (intptr_t) p, reg_set->reg_list[c].reg); + else + codegen_direct_write_64(block, p, reg_set->reg_list[c].reg); + break; - case REG_POINTER: + case REG_POINTER: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); - if ((uintptr_t)p < 256) - fatal("codegen_reg_writeback - REG_POINTER %p\n", p); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); + if ((uintptr_t) p < 256) + fatal("codegen_reg_writeback - REG_POINTER %p\n", p); #endif - codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg); - break; + codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg); + break; - case REG_DOUBLE: + case REG_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); #endif - if ((uintptr_t)p < 256) - codegen_direct_write_double_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); - else - codegen_direct_write_double(block, p, reg_set->reg_list[c].reg); - break; + if ((uintptr_t) p < 256) + codegen_direct_write_double_stack(block, (intptr_t) p, reg_set->reg_list[c].reg); + else + codegen_direct_write_double(block, p, reg_set->reg_list[c].reg); + break; - case REG_FPU_ST_BYTE: + case REG_FPU_ST_BYTE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); - else - codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); + else + codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); + break; - case REG_FPU_ST_QWORD: + case REG_FPU_ST_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); - else - codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); + else + codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); + break; - case REG_FPU_ST_DOUBLE: + case REG_FPU_ST_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); - else - codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); + else + codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); + break; - default: - fatal("codegen_reg_flush - native_size=%i\n", ireg_data[ir_reg].native_size); - } + default: + fatal("codegen_reg_flush - native_size=%i\n", ireg_data[ir_reg].native_size); + } - if (invalidate) - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; + if (invalidate) + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; } #ifdef CODEGEN_BACKEND_HAS_MOV_IMM -void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data) +void +codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data) { - int reg_idx = IREG_GET_REG(ir_reg.reg); - void *p = ireg_data[reg_idx].p; + int reg_idx = IREG_GET_REG(ir_reg.reg); + void *p = ireg_data[reg_idx].p; - switch (ireg_data[reg_idx].native_size) - { - case REG_BYTE: -#ifndef RELEASE_BUILD - if ((uintptr_t)p < 256) - fatal("codegen_reg_write_imm - REG_BYTE %p\n", p); -#endif - codegen_direct_write_8_imm(block, p, imm_data); - break; + switch (ireg_data[reg_idx].native_size) { + case REG_BYTE: +# ifndef RELEASE_BUILD + if ((uintptr_t) p < 256) + fatal("codegen_reg_write_imm - REG_BYTE %p\n", p); +# endif + codegen_direct_write_8_imm(block, p, imm_data); + break; - case REG_WORD: -#ifndef RELEASE_BUILD - if ((uintptr_t)p < 256) - fatal("codegen_reg_write_imm - REG_WORD %p\n", p); -#endif - codegen_direct_write_16_imm(block, p, imm_data); - break; + case REG_WORD: +# ifndef RELEASE_BUILD + if ((uintptr_t) p < 256) + fatal("codegen_reg_write_imm - REG_WORD %p\n", p); +# endif + codegen_direct_write_16_imm(block, p, imm_data); + break; - case REG_DWORD: - if ((uintptr_t)p < 256) - codegen_direct_write_32_imm_stack(block, (int)((uintptr_t) p), imm_data); - else - codegen_direct_write_32_imm(block, p, imm_data); - break; + case REG_DWORD: + if ((uintptr_t) p < 256) + codegen_direct_write_32_imm_stack(block, (int) ((uintptr_t) p), imm_data); + else + codegen_direct_write_32_imm(block, p, imm_data); + break; - case REG_POINTER: - case REG_QWORD: - case REG_DOUBLE: - case REG_FPU_ST_BYTE: - case REG_FPU_ST_QWORD: - case REG_FPU_ST_DOUBLE: - default: - fatal("codegen_reg_write_imm - native_size=%i\n", ireg_data[reg_idx].native_size); - } + case REG_POINTER: + case REG_QWORD: + case REG_DOUBLE: + case REG_FPU_ST_BYTE: + case REG_FPU_ST_QWORD: + case REG_FPU_ST_DOUBLE: + default: + fatal("codegen_reg_write_imm - native_size=%i\n", ireg_data[reg_idx].native_size); + } } #endif -static void alloc_reg(ir_reg_t ir_reg) +static void +alloc_reg(ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; + int c; - for (c = 0; c < nr_regs; c++) - { - if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) - { + for (c = 0; c < nr_regs; c++) { + if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { #ifndef RELEASE_BUILD - if (reg_set->regs[c].version != ir_reg.version) - fatal("alloc_reg - host_regs[c].version != ir_reg.version %i %p %p %i %i\n", c, reg_set, &host_reg_set, reg_set->regs[c].reg, ir_reg.reg); + if (reg_set->regs[c].version != ir_reg.version) + fatal("alloc_reg - host_regs[c].version != ir_reg.version %i %p %p %i %i\n", c, reg_set, &host_reg_set, reg_set->regs[c].reg, ir_reg.reg); #endif + reg_set->locked |= (1 << c); + return; + } + } +} + +static void +alloc_dest_reg(ir_reg_t ir_reg, int dest_reference) +{ + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; + int c; + + for (c = 0; c < nr_regs; c++) { + if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + if (reg_set->regs[c].version == ir_reg.version) { + reg_set->locked |= (1 << c); + } else { + /*The immediate prior version may have been + optimised out, so search backwards to find the + last valid version*/ + int prev_version = ir_reg.version - 1; + while (prev_version >= 0) { + reg_version_t *regv = ®_version[IREG_GET_REG(reg_set->regs[c].reg)][prev_version]; + + if (!(regv->flags & REG_FLAGS_DEAD) && regv->refcount == dest_reference) { reg_set->locked |= (1 << c); return; + } + prev_version--; } + fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", reg_set->regs[c].version, ir_reg.version, dest_reference); + } + return; } + } } -static void alloc_dest_reg(ir_reg_t ir_reg, int dest_reference) +void +codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; - int c; + int dest_reference = 0; - for (c = 0; c < nr_regs; c++) - { - if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) - { - if (reg_set->regs[c].version == ir_reg.version) - { - reg_set->locked |= (1 << c); - } - else - { - /*The immediate prior version may have been - optimised out, so search backwards to find the - last valid version*/ - int prev_version = ir_reg.version-1; - while (prev_version >= 0) - { - reg_version_t *regv = ®_version[IREG_GET_REG(reg_set->regs[c].reg)][prev_version]; + host_reg_set.locked = 0; + host_fp_reg_set.locked = 0; - if (!(regv->flags & REG_FLAGS_DEAD) && regv->refcount == dest_reference) - { - reg_set->locked |= (1 << c); - return; - } - prev_version--; - } - fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", reg_set->regs[c].version, ir_reg.version, dest_reference); - } - return; - } - } + if (!ir_reg_is_invalid(dest_reg_a)) { + if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(src_reg_a.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_a.version == dest_reg_a.version - 1) + dest_reference++; + if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(src_reg_b.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_b.version == dest_reg_a.version - 1) + dest_reference++; + if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(src_reg_c.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_c.version == dest_reg_a.version - 1) + dest_reference++; + } + if (!ir_reg_is_invalid(src_reg_a)) + alloc_reg(src_reg_a); + if (!ir_reg_is_invalid(src_reg_b)) + alloc_reg(src_reg_b); + if (!ir_reg_is_invalid(src_reg_c)) + alloc_reg(src_reg_c); + if (!ir_reg_is_invalid(dest_reg_a)) + alloc_dest_reg(dest_reg_a, dest_reference); } -void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c) +ir_host_reg_t +codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx) { - int dest_reference = 0; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; - host_reg_set.locked = 0; - host_fp_reg_set.locked = 0; + /*Search for required register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version == ir_reg.version) + break; - if (!ir_reg_is_invalid(dest_reg_a)) - { - if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(src_reg_a.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_a.version == dest_reg_a.version-1) - dest_reference++; - if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(src_reg_b.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_b.version == dest_reg_a.version-1) - dest_reference++; - if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(src_reg_c.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_c.version == dest_reg_a.version-1) - dest_reference++; + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version <= ir_reg.version) { + reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount++; + break; } - if (!ir_reg_is_invalid(src_reg_a)) - alloc_reg(src_reg_a); - if (!ir_reg_is_invalid(src_reg_b)) - alloc_reg(src_reg_b); - if (!ir_reg_is_invalid(src_reg_c)) - alloc_reg(src_reg_c); - if (!ir_reg_is_invalid(dest_reg_a)) - alloc_dest_reg(dest_reg_a, dest_reference); + +#ifndef RELEASE_BUILD + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount) + fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); +#endif + } + + if (c == reg_set->nr_regs) { + /*No unused registers. Search for an unlocked register with no pending reads*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!(reg_set->locked & (1 << c)) && IREG_GET_REG(reg_set->regs[c].reg) != IREG_INVALID && !ir_get_refcount(reg_set->regs[c])) + break; + } + if (c == reg_set->nr_regs) { + /*Search for any unlocked register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!(reg_set->locked & (1 << c))) + break; + } +#ifndef RELEASE_BUILD + if (c == reg_set->nr_regs) + fatal("codegen_reg_alloc_read_reg - out of registers\n"); +#endif + } + if (reg_set->dirty[c]) + codegen_reg_writeback(reg_set, block, c, 1); + codegen_reg_load(reg_set, block, c, ir_reg); + reg_set->locked |= (1 << c); + reg_set->dirty[c] = 0; + } + + reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount--; +#ifndef RELEASE_BUILD + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount == (uint8_t) -1) + fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); +#endif + + if (host_reg_idx) + *host_reg_idx = c; + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } -ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx) +ir_host_reg_t +codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; - /*Search for required register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version == ir_reg.version) - break; + if (!reg_is_native_size(ir_reg)) { + /*Read in parent register so we can do partial accesses to it*/ + ir_reg_t parent_reg; - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version <= ir_reg.version) - { - reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount++; - break; - } + parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L; + parent_reg.version = ir_reg.version - 1; + reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version - 1].refcount++; + + codegen_reg_alloc_read_reg(block, parent_reg, &c); #ifndef RELEASE_BUILD - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount) - fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); -#endif - } - - if (c == reg_set->nr_regs) - { - /*No unused registers. Search for an unlocked register with no pending reads*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!(reg_set->locked & (1 << c)) && IREG_GET_REG(reg_set->regs[c].reg) != IREG_INVALID && !ir_get_refcount(reg_set->regs[c])) - break; - } - if (c == reg_set->nr_regs) - { - /*Search for any unlocked register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!(reg_set->locked & (1 << c))) - break; - } -#ifndef RELEASE_BUILD - if (c == reg_set->nr_regs) - fatal("codegen_reg_alloc_read_reg - out of registers\n"); -#endif - } - if (reg_set->dirty[c]) - codegen_reg_writeback(reg_set, block, c, 1); - codegen_reg_load(reg_set, block, c, ir_reg); - reg_set->locked |= (1 << c); - reg_set->dirty[c] = 0; - } - - reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount--; -#ifndef RELEASE_BUILD - if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount == (uint8_t)-1) - fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); + if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version > ir_reg.version - 1) + fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, + reg_set->regs[c].reg, reg_set->regs[c].version, + ir_reg.reg, ir_reg.version); #endif - if (host_reg_idx) - *host_reg_idx = c; - return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); -} - -ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) -{ - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int c; - - if (!reg_is_native_size(ir_reg)) - { - /*Read in parent register so we can do partial accesses to it*/ - ir_reg_t parent_reg; - - parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L; - parent_reg.version = ir_reg.version - 1; - reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version - 1].refcount++; - - codegen_reg_alloc_read_reg(block, parent_reg, &c); - -#ifndef RELEASE_BUILD - if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version > ir_reg.version-1) - fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, - reg_set->regs[c].reg,reg_set->regs[c].version, - ir_reg.reg,ir_reg.version); -#endif - - reg_set->regs[c].reg = ir_reg.reg; - reg_set->regs[c].version = ir_reg.version; - reg_set->dirty[c] = 1; - return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); - } - - /*Search for previous version in host register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) - { - if (reg_set->regs[c].version <= ir_reg.version-1) - { -#ifndef RELEASE_BUILD - if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) - fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); -#endif - break; - } - } - } - - if (c == reg_set->nr_regs) - { - /*Search for unused registers*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (ir_reg_is_invalid(reg_set->regs[c])) - break; - } - - if (c == reg_set->nr_regs) - { - /*No unused registers. Search for an unlocked register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!(reg_set->locked & (1 << c))) - break; - } -#ifndef RELEASE_BUILD - if (c == reg_set->nr_regs) - fatal("codegen_reg_alloc_write_reg - out of registers\n"); -#endif - if (reg_set->dirty[c]) - codegen_reg_writeback(reg_set, block, c, 1); - } - } - - reg_set->regs[c].reg = ir_reg.reg; + reg_set->regs[c].reg = ir_reg.reg; reg_set->regs[c].version = ir_reg.version; - reg_set->dirty[c] = 1; + reg_set->dirty[c] = 1; return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); + } + + /*Search for previous version in host register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + if (reg_set->regs[c].version <= ir_reg.version - 1) { +#ifndef RELEASE_BUILD + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) + fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); +#endif + break; + } + } + } + + if (c == reg_set->nr_regs) { + /*Search for unused registers*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (ir_reg_is_invalid(reg_set->regs[c])) + break; + } + + if (c == reg_set->nr_regs) { + /*No unused registers. Search for an unlocked register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!(reg_set->locked & (1 << c))) + break; + } +#ifndef RELEASE_BUILD + if (c == reg_set->nr_regs) + fatal("codegen_reg_alloc_write_reg - out of registers\n"); +#endif + if (reg_set->dirty[c]) + codegen_reg_writeback(reg_set, block, c, 1); + } + } + + reg_set->regs[c].reg = ir_reg.reg; + reg_set->regs[c].version = ir_reg.version; + reg_set->dirty[c] = 1; + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } #ifdef CODEGEN_BACKEND_HAS_MOV_IMM -int codegen_reg_is_loaded(ir_reg_t ir_reg) +int +codegen_reg_is_loaded(ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; - /*Search for previous version in host register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) - { - if (reg_set->regs[c].version <= ir_reg.version-1) - { + /*Search for previous version in host register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + if (reg_set->regs[c].version <= ir_reg.version - 1) { +# ifndef RELEASE_BUILD + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) + fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); +# endif + return 1; + } + } + } + return 0; +} +#endif + +void +codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) +{ + host_reg_set_t *reg_set = get_reg_set(src); + int c; + int target; + + // pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version); + /*Search for required register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && reg_set->regs[c].version == src.version) + break; + } #ifndef RELEASE_BUILD - if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) - fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); -#endif - return 1; - } - } - } - return 0; -} + if (c == reg_set->nr_regs) + fatal("codegen_reg_rename: Can't find register to rename\n"); #endif + target = c; + if (reg_set->dirty[target]) + codegen_reg_writeback(reg_set, block, target, 0); + reg_set->regs[target] = dst; + reg_set->dirty[target] = 1; + // pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version); -void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) -{ - host_reg_set_t *reg_set = get_reg_set(src); - int c; - int target; - -// pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version); - /*Search for required register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && reg_set->regs[c].version == src.version) - break; - } -#ifndef RELEASE_BUILD - if (c == reg_set->nr_regs) - fatal("codegen_reg_rename: Can't find register to rename\n"); -#endif - target = c; - if (reg_set->dirty[target]) - codegen_reg_writeback(reg_set, block, target, 0); - reg_set->regs[target] = dst; - reg_set->dirty[target] = 1; -// pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version); - - /*Invalidate any stale copies of the dest register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (c == target) - continue; - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dst.reg)) - { - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } + /*Invalidate any stale copies of the dest register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (c == target) + continue; + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dst.reg)) { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; } + } } -void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) +void +codegen_reg_flush(ir_data_t *ir, codeblock_t *block) { - host_reg_set_t *reg_set; - int c; + host_reg_set_t *reg_set; + int c; - reg_set = &host_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) - { - codegen_reg_writeback(reg_set, block, c, 0); - } - if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) - { - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } + reg_set = &host_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 0); } + if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } + } - reg_set = &host_fp_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) - { - codegen_reg_writeback(reg_set, block, c, 0); - } - if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) - { - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } + reg_set = &host_fp_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 0); } + if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } + } } -void codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) +void +codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) { - host_reg_set_t *reg_set; - int c; + host_reg_set_t *reg_set; + int c; - reg_set = &host_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) - { - codegen_reg_writeback(reg_set, block, c, 1); - } - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; + reg_set = &host_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 1); } + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } - reg_set = &host_fp_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) - { - codegen_reg_writeback(reg_set, block, c, 1); - } - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; + reg_set = &host_fp_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 1); } + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } } /*Process dead register list, and optimise out register versions and uOPs where possible*/ -void codegen_reg_process_dead_list(ir_data_t *ir) +void +codegen_reg_process_dead_list(ir_data_t *ir) { - while (reg_dead_list) - { - int version = reg_dead_list & 0xff; - int reg = reg_dead_list >> 8; - reg_version_t *regv = ®_version[reg][version]; - uop_t *uop = &ir->uops[regv->parent_uop]; + while (reg_dead_list) { + int version = reg_dead_list & 0xff; + int reg = reg_dead_list >> 8; + reg_version_t *regv = ®_version[reg][version]; + uop_t *uop = &ir->uops[regv->parent_uop]; - /*Barrier uOPs should be preserved*/ - if (!(uop->type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER))) - { - uop->type = UOP_INVALID; - /*Adjust refcounts on source registers. If these drop to - zero then those registers can be considered for removal*/ - if (uop->src_reg_a.reg != IREG_INVALID) - { - reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version]; - src_regv->refcount--; - if (!src_regv->refcount) - add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_a.reg), uop->src_reg_a.version); - } - if (uop->src_reg_b.reg != IREG_INVALID) - { - reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_b.reg)][uop->src_reg_b.version]; - src_regv->refcount--; - if (!src_regv->refcount) - add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_b.reg), uop->src_reg_b.version); - } - if (uop->src_reg_c.reg != IREG_INVALID) - { - reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_c.reg)][uop->src_reg_c.version]; - src_regv->refcount--; - if (!src_regv->refcount) - add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_c.reg), uop->src_reg_c.version); - } - regv->flags |= REG_FLAGS_DEAD; - } - - reg_dead_list = regv->next; + /*Barrier uOPs should be preserved*/ + if (!(uop->type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER))) { + uop->type = UOP_INVALID; + /*Adjust refcounts on source registers. If these drop to + zero then those registers can be considered for removal*/ + if (uop->src_reg_a.reg != IREG_INVALID) { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_a.reg), uop->src_reg_a.version); + } + if (uop->src_reg_b.reg != IREG_INVALID) { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_b.reg)][uop->src_reg_b.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_b.reg), uop->src_reg_b.version); + } + if (uop->src_reg_c.reg != IREG_INVALID) { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_c.reg)][uop->src_reg_c.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_c.reg), uop->src_reg_c.version); + } + regv->flags |= REG_FLAGS_DEAD; } + + reg_dead_list = regv->next; + } } diff --git a/src/codegen_new/codegen_reg.h b/src/codegen_new/codegen_reg.h index d822a950f..c106349f5 100644 --- a/src/codegen_new/codegen_reg.h +++ b/src/codegen_new/codegen_reg.h @@ -1,276 +1,278 @@ #ifndef _CODEGEN_REG_H_ #define _CODEGEN_REG_H_ -#define IREG_REG_MASK 0xff -#define IREG_SIZE_SHIFT 8 -#define IREG_SIZE_MASK (7 << IREG_SIZE_SHIFT) +#define IREG_REG_MASK 0xff +#define IREG_SIZE_SHIFT 8 +#define IREG_SIZE_MASK (7 << IREG_SIZE_SHIFT) -#define IREG_GET_REG(reg) ((reg) & IREG_REG_MASK) -#define IREG_GET_SIZE(reg) ((reg) & IREG_SIZE_MASK) +#define IREG_GET_REG(reg) ((reg) &IREG_REG_MASK) +#define IREG_GET_SIZE(reg) ((reg) &IREG_SIZE_MASK) -#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT) -#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT) -#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) -#define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT) -#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT) -#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT) +#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT) +#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT) +#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) +#define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT) +#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT) +#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT) -enum -{ - IREG_EAX = 0, - IREG_ECX = 1, - IREG_EDX = 2, - IREG_EBX = 3, - IREG_ESP = 4, - IREG_EBP = 5, - IREG_ESI = 6, - IREG_EDI = 7, +enum { + IREG_EAX = 0, + IREG_ECX = 1, + IREG_EDX = 2, + IREG_EBX = 3, + IREG_ESP = 4, + IREG_EBP = 5, + IREG_ESI = 6, + IREG_EDI = 7, - IREG_flags_op = 8, - IREG_flags_res = 9, - IREG_flags_op1 = 10, - IREG_flags_op2 = 11, + IREG_flags_op = 8, + IREG_flags_res = 9, + IREG_flags_op1 = 10, + IREG_flags_op2 = 11, - IREG_pc = 12, - IREG_oldpc = 13, + IREG_pc = 12, + IREG_oldpc = 13, - IREG_eaaddr = 14, - IREG_ea_seg = 15, - IREG_op32 = 16, - IREG_ssegsx = 17, + IREG_eaaddr = 14, + IREG_ea_seg = 15, + IREG_op32 = 16, + IREG_ssegsx = 17, - IREG_rm_mod_reg = 18, + IREG_rm_mod_reg = 18, - IREG_acycs = 19, - IREG_cycles = 20, + IREG_acycs = 19, + IREG_cycles = 20, - IREG_CS_base = 21, - IREG_DS_base = 22, - IREG_ES_base = 23, - IREG_FS_base = 24, - IREG_GS_base = 25, - IREG_SS_base = 26, + IREG_CS_base = 21, + IREG_DS_base = 22, + IREG_ES_base = 23, + IREG_FS_base = 24, + IREG_GS_base = 25, + IREG_SS_base = 26, - IREG_CS_seg = 27, - IREG_DS_seg = 28, - IREG_ES_seg = 29, - IREG_FS_seg = 30, - IREG_GS_seg = 31, - IREG_SS_seg = 32, + IREG_CS_seg = 27, + IREG_DS_seg = 28, + IREG_ES_seg = 29, + IREG_FS_seg = 30, + IREG_GS_seg = 31, + IREG_SS_seg = 32, - /*Temporary registers are stored on the stack, and are not guaranteed to - be preserved across uOPs. They will not be written back if they will - not be read again.*/ - IREG_temp0 = 33, - IREG_temp1 = 34, - IREG_temp2 = 35, - IREG_temp3 = 36, + /*Temporary registers are stored on the stack, and are not guaranteed to + be preserved across uOPs. They will not be written back if they will + not be read again.*/ + IREG_temp0 = 33, + IREG_temp1 = 34, + IREG_temp2 = 35, + IREG_temp3 = 36, - IREG_FPU_TOP = 37, + IREG_FPU_TOP = 37, - IREG_temp0d = 38, - IREG_temp1d = 39, + IREG_temp0d = 38, + IREG_temp1d = 39, - /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() - to access. - When CODEBLOCK_STATIC_TOP is set, the physical register number will be - used directly to index the stack. When it is clear, the difference - between the current value of TOP and the value when the block was - first compiled will be added to adjust for any changes in TOP.*/ - IREG_ST0 = 40, - IREG_ST1 = 41, - IREG_ST2 = 42, - IREG_ST3 = 43, - IREG_ST4 = 44, - IREG_ST5 = 45, - IREG_ST6 = 46, - IREG_ST7 = 47, + /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() + to access. + When CODEBLOCK_STATIC_TOP is set, the physical register number will be + used directly to index the stack. When it is clear, the difference + between the current value of TOP and the value when the block was + first compiled will be added to adjust for any changes in TOP.*/ + IREG_ST0 = 40, + IREG_ST1 = 41, + IREG_ST2 = 42, + IREG_ST3 = 43, + IREG_ST4 = 44, + IREG_ST5 = 45, + IREG_ST6 = 46, + IREG_ST7 = 47, - IREG_tag0 = 48, - IREG_tag1 = 49, - IREG_tag2 = 50, - IREG_tag3 = 51, - IREG_tag4 = 52, - IREG_tag5 = 53, - IREG_tag6 = 54, - IREG_tag7 = 55, + IREG_tag0 = 48, + IREG_tag1 = 49, + IREG_tag2 = 50, + IREG_tag3 = 51, + IREG_tag4 = 52, + IREG_tag5 = 53, + IREG_tag6 = 54, + IREG_tag7 = 55, - IREG_ST0_i64 = 56, - IREG_ST1_i64 = 57, - IREG_ST2_i64 = 58, - IREG_ST3_i64 = 59, - IREG_ST4_i64 = 60, - IREG_ST5_i64 = 61, - IREG_ST6_i64 = 62, - IREG_ST7_i64 = 63, + IREG_ST0_i64 = 56, + IREG_ST1_i64 = 57, + IREG_ST2_i64 = 58, + IREG_ST3_i64 = 59, + IREG_ST4_i64 = 60, + IREG_ST5_i64 = 61, + IREG_ST6_i64 = 62, + IREG_ST7_i64 = 63, - IREG_MM0x = 64, - IREG_MM1x = 65, - IREG_MM2x = 66, - IREG_MM3x = 67, - IREG_MM4x = 68, - IREG_MM5x = 69, - IREG_MM6x = 70, - IREG_MM7x = 71, + IREG_MM0x = 64, + IREG_MM1x = 65, + IREG_MM2x = 66, + IREG_MM3x = 67, + IREG_MM4x = 68, + IREG_MM5x = 69, + IREG_MM6x = 70, + IREG_MM7x = 71, - IREG_NPXCx = 72, - IREG_NPXSx = 73, + IREG_NPXCx = 72, + IREG_NPXSx = 73, - IREG_flagsx = 74, - IREG_eflagsx = 75, + IREG_flagsx = 74, + IREG_eflagsx = 75, - IREG_CS_limit_low = 76, - IREG_DS_limit_low = 77, - IREG_ES_limit_low = 78, - IREG_FS_limit_low = 79, - IREG_GS_limit_low = 80, - IREG_SS_limit_low = 81, + IREG_CS_limit_low = 76, + IREG_DS_limit_low = 77, + IREG_ES_limit_low = 78, + IREG_FS_limit_low = 79, + IREG_GS_limit_low = 80, + IREG_SS_limit_low = 81, - IREG_CS_limit_high = 82, - IREG_DS_limit_high = 83, - IREG_ES_limit_high = 84, - IREG_FS_limit_high = 85, - IREG_GS_limit_high = 86, - IREG_SS_limit_high = 87, + IREG_CS_limit_high = 82, + IREG_DS_limit_high = 83, + IREG_ES_limit_high = 84, + IREG_FS_limit_high = 85, + IREG_GS_limit_high = 86, + IREG_SS_limit_high = 87, - IREG_COUNT = 88, + IREG_COUNT = 88, - IREG_INVALID = 255, + IREG_INVALID = 255, - IREG_AX = IREG_EAX + IREG_SIZE_W, - IREG_CX = IREG_ECX + IREG_SIZE_W, - IREG_DX = IREG_EDX + IREG_SIZE_W, - IREG_BX = IREG_EBX + IREG_SIZE_W, - IREG_SP = IREG_ESP + IREG_SIZE_W, - IREG_BP = IREG_EBP + IREG_SIZE_W, - IREG_SI = IREG_ESI + IREG_SIZE_W, - IREG_DI = IREG_EDI + IREG_SIZE_W, + IREG_AX = IREG_EAX + IREG_SIZE_W, + IREG_CX = IREG_ECX + IREG_SIZE_W, + IREG_DX = IREG_EDX + IREG_SIZE_W, + IREG_BX = IREG_EBX + IREG_SIZE_W, + IREG_SP = IREG_ESP + IREG_SIZE_W, + IREG_BP = IREG_EBP + IREG_SIZE_W, + IREG_SI = IREG_ESI + IREG_SIZE_W, + IREG_DI = IREG_EDI + IREG_SIZE_W, - IREG_AL = IREG_EAX + IREG_SIZE_B, - IREG_CL = IREG_ECX + IREG_SIZE_B, - IREG_DL = IREG_EDX + IREG_SIZE_B, - IREG_BL = IREG_EBX + IREG_SIZE_B, + IREG_AL = IREG_EAX + IREG_SIZE_B, + IREG_CL = IREG_ECX + IREG_SIZE_B, + IREG_DL = IREG_EDX + IREG_SIZE_B, + IREG_BL = IREG_EBX + IREG_SIZE_B, - IREG_AH = IREG_EAX + IREG_SIZE_BH, - IREG_CH = IREG_ECX + IREG_SIZE_BH, - IREG_DH = IREG_EDX + IREG_SIZE_BH, - IREG_BH = IREG_EBX + IREG_SIZE_BH, + IREG_AH = IREG_EAX + IREG_SIZE_BH, + IREG_CH = IREG_ECX + IREG_SIZE_BH, + IREG_DH = IREG_EDX + IREG_SIZE_BH, + IREG_BH = IREG_EBX + IREG_SIZE_BH, - IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W, - IREG_flags_op1_W = IREG_flags_op1 + IREG_SIZE_W, - IREG_flags_op2_W = IREG_flags_op2 + IREG_SIZE_W, + IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W, + IREG_flags_op1_W = IREG_flags_op1 + IREG_SIZE_W, + IREG_flags_op2_W = IREG_flags_op2 + IREG_SIZE_W, - IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B, - IREG_flags_op1_B = IREG_flags_op1 + IREG_SIZE_B, - IREG_flags_op2_B = IREG_flags_op2 + IREG_SIZE_B, + IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B, + IREG_flags_op1_B = IREG_flags_op1 + IREG_SIZE_B, + IREG_flags_op2_B = IREG_flags_op2 + IREG_SIZE_B, - IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, - IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, - IREG_temp2_W = IREG_temp2 + IREG_SIZE_W, - IREG_temp3_W = IREG_temp3 + IREG_SIZE_W, + IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, + IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, + IREG_temp2_W = IREG_temp2 + IREG_SIZE_W, + IREG_temp3_W = IREG_temp3 + IREG_SIZE_W, - IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, - IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, - IREG_temp2_B = IREG_temp2 + IREG_SIZE_B, - IREG_temp3_B = IREG_temp3 + IREG_SIZE_B, + IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, + IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, + IREG_temp2_B = IREG_temp2 + IREG_SIZE_B, + IREG_temp3_B = IREG_temp3 + IREG_SIZE_B, - IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, - IREG_temp1_D = IREG_temp1d + IREG_SIZE_D, + IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, + IREG_temp1_D = IREG_temp1d + IREG_SIZE_D, - IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q, - IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q, + IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q, + IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q, - IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, + IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, - IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W, - IREG_DS_seg_W = IREG_DS_seg + IREG_SIZE_W, - IREG_ES_seg_W = IREG_ES_seg + IREG_SIZE_W, - IREG_FS_seg_W = IREG_FS_seg + IREG_SIZE_W, - IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W, - IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W, + IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W, + IREG_DS_seg_W = IREG_DS_seg + IREG_SIZE_W, + IREG_ES_seg_W = IREG_ES_seg + IREG_SIZE_W, + IREG_FS_seg_W = IREG_FS_seg + IREG_SIZE_W, + IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W, + IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W, - IREG_MM0 = IREG_MM0x + IREG_SIZE_Q, - IREG_MM1 = IREG_MM1x + IREG_SIZE_Q, - IREG_MM2 = IREG_MM2x + IREG_SIZE_Q, - IREG_MM3 = IREG_MM3x + IREG_SIZE_Q, - IREG_MM4 = IREG_MM4x + IREG_SIZE_Q, - IREG_MM5 = IREG_MM5x + IREG_SIZE_Q, - IREG_MM6 = IREG_MM6x + IREG_SIZE_Q, - IREG_MM7 = IREG_MM7x + IREG_SIZE_Q, + IREG_MM0 = IREG_MM0x + IREG_SIZE_Q, + IREG_MM1 = IREG_MM1x + IREG_SIZE_Q, + IREG_MM2 = IREG_MM2x + IREG_SIZE_Q, + IREG_MM3 = IREG_MM3x + IREG_SIZE_Q, + IREG_MM4 = IREG_MM4x + IREG_SIZE_Q, + IREG_MM5 = IREG_MM5x + IREG_SIZE_Q, + IREG_MM6 = IREG_MM6x + IREG_SIZE_Q, + IREG_MM7 = IREG_MM7x + IREG_SIZE_Q, - IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, - IREG_NPXS = IREG_NPXSx + IREG_SIZE_W, + IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, + IREG_NPXS = IREG_NPXSx + IREG_SIZE_W, - IREG_ssegs = IREG_ssegsx + IREG_SIZE_B, + IREG_ssegs = IREG_ssegsx + IREG_SIZE_B, - IREG_flags = IREG_flagsx + IREG_SIZE_W, - IREG_eflags = IREG_eflagsx + IREG_SIZE_W + IREG_flags = IREG_flagsx + IREG_SIZE_W, + IREG_eflags = IREG_eflagsx + IREG_SIZE_W }; -#define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) -#define IREG_16(reg) ((reg) + IREG_AX) -#define IREG_32(reg) ((reg) + IREG_EAX) +#define IREG_8(reg) (((reg) &4) ? (((reg) &3) + IREG_AH) : ((reg) + IREG_AL)) +#define IREG_16(reg) ((reg) + IREG_AX) +#define IREG_32(reg) ((reg) + IREG_EAX) -#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) -#define IREG_ST_i64(r) (IREG_ST0_i64 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) -#define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) -#define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B) +#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) +#define IREG_ST_i64(r) (IREG_ST0_i64 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) +#define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) +#define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B) -#define IREG_MM(reg) ((reg) + IREG_MM0) +#define IREG_MM(reg) ((reg) + IREG_MM0) #define IREG_TOP_diff_stack_offset 32 -static inline int ireg_seg_base(x86seg *seg) +static inline int +ireg_seg_base(x86seg *seg) { - if (seg == &cpu_state.seg_cs) - return IREG_CS_base; - if (seg == &cpu_state.seg_ds) - return IREG_DS_base; - if (seg == &cpu_state.seg_es) - return IREG_ES_base; - if (seg == &cpu_state.seg_fs) - return IREG_FS_base; - if (seg == &cpu_state.seg_gs) - return IREG_GS_base; - if (seg == &cpu_state.seg_ss) - return IREG_SS_base; - fatal("ireg_seg_base : unknown segment\n"); - return 0; + if (seg == &cpu_state.seg_cs) + return IREG_CS_base; + if (seg == &cpu_state.seg_ds) + return IREG_DS_base; + if (seg == &cpu_state.seg_es) + return IREG_ES_base; + if (seg == &cpu_state.seg_fs) + return IREG_FS_base; + if (seg == &cpu_state.seg_gs) + return IREG_GS_base; + if (seg == &cpu_state.seg_ss) + return IREG_SS_base; + fatal("ireg_seg_base : unknown segment\n"); + return 0; } -static inline int ireg_seg_limit_low(x86seg *seg) +static inline int +ireg_seg_limit_low(x86seg *seg) { - if (seg == &cpu_state.seg_cs) - return IREG_CS_limit_low; - if (seg == &cpu_state.seg_ds) - return IREG_DS_limit_low; - if (seg == &cpu_state.seg_es) - return IREG_ES_limit_low; - if (seg == &cpu_state.seg_fs) - return IREG_FS_limit_low; - if (seg == &cpu_state.seg_gs) - return IREG_GS_limit_low; - if (seg == &cpu_state.seg_ss) - return IREG_SS_limit_low; - fatal("ireg_seg_limit_low : unknown segment\n"); - return 0; + if (seg == &cpu_state.seg_cs) + return IREG_CS_limit_low; + if (seg == &cpu_state.seg_ds) + return IREG_DS_limit_low; + if (seg == &cpu_state.seg_es) + return IREG_ES_limit_low; + if (seg == &cpu_state.seg_fs) + return IREG_FS_limit_low; + if (seg == &cpu_state.seg_gs) + return IREG_GS_limit_low; + if (seg == &cpu_state.seg_ss) + return IREG_SS_limit_low; + fatal("ireg_seg_limit_low : unknown segment\n"); + return 0; } -static inline int ireg_seg_limit_high(x86seg *seg) +static inline int +ireg_seg_limit_high(x86seg *seg) { - if (seg == &cpu_state.seg_cs) - return IREG_CS_limit_high; - if (seg == &cpu_state.seg_ds) - return IREG_DS_limit_high; - if (seg == &cpu_state.seg_es) - return IREG_ES_limit_high; - if (seg == &cpu_state.seg_fs) - return IREG_FS_limit_high; - if (seg == &cpu_state.seg_gs) - return IREG_GS_limit_high; - if (seg == &cpu_state.seg_ss) - return IREG_SS_limit_high; - fatal("ireg_seg_limit_high : unknown segment\n"); - return 0; + if (seg == &cpu_state.seg_cs) + return IREG_CS_limit_high; + if (seg == &cpu_state.seg_ds) + return IREG_DS_limit_high; + if (seg == &cpu_state.seg_es) + return IREG_ES_limit_high; + if (seg == &cpu_state.seg_fs) + return IREG_FS_limit_high; + if (seg == &cpu_state.seg_gs) + return IREG_GS_limit_high; + if (seg == &cpu_state.seg_ss) + return IREG_SS_limit_high; + fatal("ireg_seg_limit_high : unknown segment\n"); + return 0; } extern uint8_t reg_last_version[IREG_COUNT]; @@ -279,18 +281,18 @@ extern uint8_t reg_last_version[IREG_COUNT]; apparently required or not. Do not optimise out.*/ #define REG_FLAGS_REQUIRED (1 << 0) /*This register and the parent uOP have been optimised out.*/ -#define REG_FLAGS_DEAD (1 << 1) +#define REG_FLAGS_DEAD (1 << 1) typedef struct { - /*Refcount of pending reads on this register version*/ - uint8_t refcount; - /*Flags*/ - uint8_t flags; - /*uOP that generated this register version*/ - uint16_t parent_uop; - /*Pointer to next register version in dead register list*/ - uint16_t next; + /*Refcount of pending reads on this register version*/ + uint8_t refcount; + /*Flags*/ + uint8_t flags; + /*uOP that generated this register version*/ + uint16_t parent_uop; + /*Pointer to next register version in dead register list*/ + uint16_t next; } reg_version_t; extern reg_version_t reg_version[IREG_COUNT][256]; @@ -299,16 +301,17 @@ extern reg_version_t reg_version[IREG_COUNT][256]; can be optimised out*/ extern uint16_t reg_dead_list; -static inline void add_to_dead_list(reg_version_t *regv, int reg, int version) +static inline void +add_to_dead_list(reg_version_t *regv, int reg, int version) { - regv->next = reg_dead_list; - reg_dead_list = version | (reg << 8); + regv->next = reg_dead_list; + reg_dead_list = version | (reg << 8); } typedef struct { - uint16_t reg; - uint16_t version; + uint16_t reg; + uint16_t version; } ir_reg_t; extern ir_reg_t invalid_ir_reg; @@ -317,85 +320,86 @@ typedef uint16_t ir_host_reg_t; extern int max_version_refcount; -#define REG_VERSION_MAX 250 +#define REG_VERSION_MAX 250 #define REG_REFCOUNT_MAX 250 -static inline ir_reg_t codegen_reg_read(int reg) +static inline ir_reg_t +codegen_reg_read(int reg) { - ir_reg_t ireg; - reg_version_t *version; + ir_reg_t ireg; + reg_version_t *version; #ifndef RELEASE_BUILD - if (IREG_GET_REG(reg) == IREG_INVALID) - fatal("codegen_reg_read - IREG_INVALID\n"); + if (IREG_GET_REG(reg) == IREG_INVALID) + fatal("codegen_reg_read - IREG_INVALID\n"); #endif - ireg.reg = reg; - ireg.version = reg_last_version[IREG_GET_REG(reg)]; - version = ®_version[IREG_GET_REG(ireg.reg)][ireg.version]; - version->flags = 0; - version->refcount++; + ireg.reg = reg; + ireg.version = reg_last_version[IREG_GET_REG(reg)]; + version = ®_version[IREG_GET_REG(ireg.reg)][ireg.version]; + version->flags = 0; + version->refcount++; #ifndef RELEASE_BUILD - if (!version->refcount) - fatal("codegen_reg_read - refcount overflow\n"); - else + if (!version->refcount) + fatal("codegen_reg_read - refcount overflow\n"); + else #endif if (version->refcount > REG_REFCOUNT_MAX) - CPU_BLOCK_END(); - if (version->refcount > max_version_refcount) - max_version_refcount = version->refcount; -// pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); - return ireg; + CPU_BLOCK_END(); + if (version->refcount > max_version_refcount) + max_version_refcount = version->refcount; + // pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); + return ireg; } int reg_is_native_size(ir_reg_t ir_reg); -static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) +static inline ir_reg_t +codegen_reg_write(int reg, int uop_nr) { - ir_reg_t ireg; - int last_version = reg_last_version[IREG_GET_REG(reg)]; - reg_version_t *version; + ir_reg_t ireg; + int last_version = reg_last_version[IREG_GET_REG(reg)]; + reg_version_t *version; #ifndef RELEASE_BUILD - if (IREG_GET_REG(reg) == IREG_INVALID) - fatal("codegen_reg_write - IREG_INVALID\n"); + if (IREG_GET_REG(reg) == IREG_INVALID) + fatal("codegen_reg_write - IREG_INVALID\n"); #endif - ireg.reg = reg; - ireg.version = last_version + 1; + ireg.reg = reg; + ireg.version = last_version + 1; - if (IREG_GET_REG(reg) > IREG_EBX && last_version && !reg_version[IREG_GET_REG(reg)][last_version].refcount && - !(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED)) - { - if (reg_is_native_size(ireg)) /*Non-native size registers have an implicit dependency on the previous version, so don't add to dead list*/ - add_to_dead_list(®_version[IREG_GET_REG(reg)][last_version], IREG_GET_REG(reg), last_version); - } + if (IREG_GET_REG(reg) > IREG_EBX && last_version && !reg_version[IREG_GET_REG(reg)][last_version].refcount && !(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED)) { + if (reg_is_native_size(ireg)) /*Non-native size registers have an implicit dependency on the previous version, so don't add to dead list*/ + add_to_dead_list(®_version[IREG_GET_REG(reg)][last_version], IREG_GET_REG(reg), last_version); + } - reg_last_version[IREG_GET_REG(reg)]++; + reg_last_version[IREG_GET_REG(reg)]++; #ifndef RELEASE_BUILD - if (!reg_last_version[IREG_GET_REG(reg)]) - fatal("codegen_reg_write - version overflow\n"); - else + if (!reg_last_version[IREG_GET_REG(reg)]) + fatal("codegen_reg_write - version overflow\n"); + else #endif if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) - CPU_BLOCK_END(); - if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount) - max_version_refcount = reg_last_version[IREG_GET_REG(reg)]; + CPU_BLOCK_END(); + if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount) + max_version_refcount = reg_last_version[IREG_GET_REG(reg)]; - version = ®_version[IREG_GET_REG(reg)][ireg.version]; - version->refcount = 0; - version->flags = 0; - version->parent_uop = uop_nr; -// pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK); - return ireg; + version = ®_version[IREG_GET_REG(reg)][ireg.version]; + version->refcount = 0; + version->flags = 0; + version->parent_uop = uop_nr; + // pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK); + return ireg; } -static inline int ir_reg_is_invalid(ir_reg_t ir_reg) +static inline int +ir_reg_is_invalid(ir_reg_t ir_reg) { - return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); + return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); } struct ir_data_t; -void codegen_reg_reset(); +void codegen_reg_reset(void); /*Write back all dirty registers*/ void codegen_reg_flush(struct ir_data_t *ir, codeblock_t *block); /*Write back and evict all registers*/ @@ -405,7 +409,7 @@ void codegen_reg_flush_invalidate(struct ir_data_t *ir, codeblock_t *block); void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c); #ifdef CODEGEN_BACKEND_HAS_MOV_IMM -int codegen_reg_is_loaded(ir_reg_t ir_reg); +int codegen_reg_is_loaded(ir_reg_t ir_reg); void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data); #endif @@ -414,6 +418,6 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg); void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst); -void codegen_reg_mark_as_required(); +void codegen_reg_mark_as_required(void); void codegen_reg_process_dead_list(struct ir_data_t *ir); #endif diff --git a/src/config.c b/src/config.c index e433e4071..39826b3b5 100644 --- a/src/config.c +++ b/src/config.c @@ -1,29 +1,29 @@ /* * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Configuration file handler. + * Configuration file handler. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Overdoze, - * David Hrdlička, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Overdoze, + * David Hrdlička, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2018,2019 David Hrdlička. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2018,2019 David Hrdlička. * * NOTE: Forcing config files to be in Unicode encoding breaks - * it on Windows XP, and possibly also Vista. Use the - * -DANSI_CFG for use on these systems. + * it on Windows XP, and possibly also Vista. Use the + * -DANSI_CFG for use on these systems. */ #include @@ -494,8 +494,8 @@ load_machine(void) mem_size = (((machine_has_bus(machine, MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); #endif - if (mem_size > 2097152) - mem_size = 2097152; + if (mem_size > machine_get_max_ram(machine)) + mem_size = machine_get_max_ram(machine); cpu_use_dynarec = !!ini_section_get_int(cat, "cpu_use_dynarec", 0); @@ -713,7 +713,7 @@ load_network(void) ini_section_t cat = ini_find_section(config, "Network"); char *p; char temp[512]; - int c = 0, min = 0; + uint16_t c = 0, min = 0; /* Handle legacy configuration which supported only one NIC */ p = ini_section_get_string(cat, "net_card", NULL); @@ -736,9 +736,9 @@ load_network(void) if (p != NULL) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { if (network_ndev == 1) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2094, (wchar_t *) IDS_2129); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130); } else if (network_dev_to_id(p) == -1) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2129); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130); } strcpy(net_cards_conf[c].host_dev_name, "none"); } else { @@ -783,9 +783,9 @@ load_network(void) if (p != NULL) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { if (network_ndev == 1) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2094, (wchar_t *) IDS_2129); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130); } else if (network_dev_to_id(p) == -1) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2129); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130); } strcpy(net_cards_conf[c].host_dev_name, "none"); } else { @@ -999,7 +999,7 @@ load_hard_disks(void) case HDD_BUS_IDE: max_spt = 63; - max_hpc = 16; + max_hpc = 255; max_tracks = 266305; break; diff --git a/src/cpu/386.c b/src/cpu/386.c index ecf426270..a5bae7de6 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -196,20 +196,20 @@ exec386(int cycs) } } else if (trap) { flags_rebuild(); - trap = 0; + trap = 0; #ifndef USE_NEW_DYNAREC - oldcs = CS; + oldcs = CS; #endif - cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; - x86_int(1); + cpu_state.oldpc = cpu_state.pc; + dr[6] |= 0x4000; + x86_int(1); } if (smi_line) enter_smm_check(0); else if (nmi && nmi_enable && nmi_mask) { #ifndef USE_NEW_DYNAREC - oldcs = CS; + oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; x86_int(2); diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 3c0cd168a..f8e7c11ce 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -6,7 +6,7 @@ #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H #include <86box/86box.h> @@ -28,20 +28,19 @@ #include "x86seg.h" #ifdef USE_DYNAREC -#include "codegen.h" -#define CPU_BLOCK_END() cpu_block_end = 1 +# include "codegen.h" +# define CPU_BLOCK_END() cpu_block_end = 1 #else -#define CPU_BLOCK_END() +# define CPU_BLOCK_END() #endif - x86seg gdt, ldt, idt, tr; uint32_t cr2, cr3, cr4; uint32_t dr[8]; uint32_t use32; -int stack32; +int stack32; uint32_t *eal_r, *eal_w; @@ -57,11 +56,10 @@ uint32_t cpu_cur_status = 0; extern uint8_t *pccache2; -extern int optype; +extern int optype; extern uint32_t pccache; - -int in_sys = 0, unmask_a20_in_smm = 0; +int in_sys = 0, unmask_a20_in_smm = 0; uint32_t old_rammask = 0xffffffff; int soft_reset_mask = 0; @@ -72,348 +70,339 @@ int smm_in_hlt = 0, smi_block = 0; uint32_t addr64, addr64_2; uint32_t addr64a[8], addr64a_2[8]; -static pc_timer_t *cpu_fast_off_timer = NULL; -static double cpu_fast_off_period = 0.0; - - -#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) -#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) -#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) +static pc_timer_t *cpu_fast_off_timer = NULL; +static double cpu_fast_off_period = 0.0; +#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) /* These #define's and enum have been borrowed from Bochs. */ /* SMM feature masks */ -#define SMM_IO_INSTRUCTION_RESTART (0x00010000) -#define SMM_SMBASE_RELOCATION (0x00020000) -#define SMM_REVISION (0x20000000) +#define SMM_IO_INSTRUCTION_RESTART (0x00010000) +#define SMM_SMBASE_RELOCATION (0x00020000) +#define SMM_REVISION (0x20000000) /* TODO: Which CPU added SMBASE relocation? */ -#define SMM_REVISION_ID (SMM_SMBASE_RELOCATION | SMM_IO_INSTRUCTION_RESTART | SMM_REVISION) +#define SMM_REVISION_ID (SMM_SMBASE_RELOCATION | SMM_IO_INSTRUCTION_RESTART | SMM_REVISION) #define SMM_SAVE_STATE_MAP_SIZE 128 - enum SMMRAM_Fields_386_To_P5 { - SMRAM_FIELD_P5_CR0 = 0, /* 1FC */ - SMRAM_FIELD_P5_CR3, /* 1F8 */ - SMRAM_FIELD_P5_EFLAGS, /* 1F4 */ - SMRAM_FIELD_P5_EIP, /* 1F0 */ - SMRAM_FIELD_P5_EDI, /* 1EC */ - SMRAM_FIELD_P5_ESI, /* 1E8 */ - SMRAM_FIELD_P5_EBP, /* 1E4 */ - SMRAM_FIELD_P5_ESP, /* 1E0 */ - SMRAM_FIELD_P5_EBX, /* 1DC */ - SMRAM_FIELD_P5_EDX, /* 1D8 */ - SMRAM_FIELD_P5_ECX, /* 1D4 */ - SMRAM_FIELD_P5_EAX, /* 1D0 */ - SMRAM_FIELD_P5_DR6, /* 1CC */ - SMRAM_FIELD_P5_DR7, /* 1C8 */ - SMRAM_FIELD_P5_TR_SELECTOR, /* 1C4 */ - SMRAM_FIELD_P5_LDTR_SELECTOR, /* 1C0 */ - SMRAM_FIELD_P5_GS_SELECTOR, /* 1BC */ - SMRAM_FIELD_P5_FS_SELECTOR, /* 1B8 */ - SMRAM_FIELD_P5_DS_SELECTOR, /* 1B4 */ - SMRAM_FIELD_P5_SS_SELECTOR, /* 1B0 */ - SMRAM_FIELD_P5_CS_SELECTOR, /* 1AC */ - SMRAM_FIELD_P5_ES_SELECTOR, /* 1A8 */ - SMRAM_FIELD_P5_TR_ACCESS, /* 1A4 */ - SMRAM_FIELD_P5_TR_BASE, /* 1A0 */ - SMRAM_FIELD_P5_TR_LIMIT, /* 19C */ - SMRAM_FIELD_P5_IDTR_ACCESS, /* 198 */ - SMRAM_FIELD_P5_IDTR_BASE, /* 194 */ - SMRAM_FIELD_P5_IDTR_LIMIT, /* 190 */ - SMRAM_FIELD_P5_GDTR_ACCESS, /* 18C */ - SMRAM_FIELD_P5_GDTR_BASE, /* 188 */ - SMRAM_FIELD_P5_GDTR_LIMIT, /* 184 */ - SMRAM_FIELD_P5_LDTR_ACCESS, /* 180 */ - SMRAM_FIELD_P5_LDTR_BASE, /* 17C */ - SMRAM_FIELD_P5_LDTR_LIMIT, /* 178 */ - SMRAM_FIELD_P5_GS_ACCESS, /* 174 */ - SMRAM_FIELD_P5_GS_BASE, /* 170 */ - SMRAM_FIELD_P5_GS_LIMIT, /* 16C */ - SMRAM_FIELD_P5_FS_ACCESS, /* 168 */ - SMRAM_FIELD_P5_FS_BASE, /* 164 */ - SMRAM_FIELD_P5_FS_LIMIT, /* 160 */ - SMRAM_FIELD_P5_DS_ACCESS, /* 15C */ - SMRAM_FIELD_P5_DS_BASE, /* 158 */ - SMRAM_FIELD_P5_DS_LIMIT, /* 154 */ - SMRAM_FIELD_P5_SS_ACCESS, /* 150 */ - SMRAM_FIELD_P5_SS_BASE, /* 14C */ - SMRAM_FIELD_P5_SS_LIMIT, /* 148 */ - SMRAM_FIELD_P5_CS_ACCESS, /* 144 */ - SMRAM_FIELD_P5_CS_BASE, /* 140 */ - SMRAM_FIELD_P5_CS_LIMIT, /* 13C */ - SMRAM_FIELD_P5_ES_ACCESS, /* 138 */ - SMRAM_FIELD_P5_ES_BASE, /* 134 */ - SMRAM_FIELD_P5_ES_LIMIT, /* 130 */ - SMRAM_FIELD_P5_UNWRITTEN_1, /* 12C */ - SMRAM_FIELD_P5_CR4, /* 128 */ - SMRAM_FIELD_P5_ALTERNATE_DR6, /* 124 */ - SMRAM_FIELD_P5_RESERVED_1, /* 120 */ - SMRAM_FIELD_P5_RESERVED_2, /* 11C */ - SMRAM_FIELD_P5_RESERVED_3, /* 118 */ - SMRAM_FIELD_P5_RESERVED_4, /* 114 */ - SMRAM_FIELD_P5_IO_RESTART_EIP, /* 110 */ - SMRAM_FIELD_P5_IO_RESTART_ESI, /* 10C */ - SMRAM_FIELD_P5_IO_RESTART_ECX, /* 108 */ - SMRAM_FIELD_P5_IO_RESTART_EDI, /* 104 */ - SMRAM_FIELD_P5_AUTOHALT_RESTART, /* 100 */ - SMRAM_FIELD_P5_SMM_REVISION_ID, /* 0FC */ - SMRAM_FIELD_P5_SMBASE_OFFSET, /* 0F8 */ - SMRAM_FIELD_AM486_CR2, /* 0F4 */ - SMRAM_FIELD_AM486_DR0, /* 0F0 */ - SMRAM_FIELD_AM486_DR1, /* 0EC */ - SMRAM_FIELD_AM486_DR2, /* 0E8 */ - SMRAM_FIELD_AM486_DR3, /* 0E4 */ + SMRAM_FIELD_P5_CR0 = 0, /* 1FC */ + SMRAM_FIELD_P5_CR3, /* 1F8 */ + SMRAM_FIELD_P5_EFLAGS, /* 1F4 */ + SMRAM_FIELD_P5_EIP, /* 1F0 */ + SMRAM_FIELD_P5_EDI, /* 1EC */ + SMRAM_FIELD_P5_ESI, /* 1E8 */ + SMRAM_FIELD_P5_EBP, /* 1E4 */ + SMRAM_FIELD_P5_ESP, /* 1E0 */ + SMRAM_FIELD_P5_EBX, /* 1DC */ + SMRAM_FIELD_P5_EDX, /* 1D8 */ + SMRAM_FIELD_P5_ECX, /* 1D4 */ + SMRAM_FIELD_P5_EAX, /* 1D0 */ + SMRAM_FIELD_P5_DR6, /* 1CC */ + SMRAM_FIELD_P5_DR7, /* 1C8 */ + SMRAM_FIELD_P5_TR_SELECTOR, /* 1C4 */ + SMRAM_FIELD_P5_LDTR_SELECTOR, /* 1C0 */ + SMRAM_FIELD_P5_GS_SELECTOR, /* 1BC */ + SMRAM_FIELD_P5_FS_SELECTOR, /* 1B8 */ + SMRAM_FIELD_P5_DS_SELECTOR, /* 1B4 */ + SMRAM_FIELD_P5_SS_SELECTOR, /* 1B0 */ + SMRAM_FIELD_P5_CS_SELECTOR, /* 1AC */ + SMRAM_FIELD_P5_ES_SELECTOR, /* 1A8 */ + SMRAM_FIELD_P5_TR_ACCESS, /* 1A4 */ + SMRAM_FIELD_P5_TR_BASE, /* 1A0 */ + SMRAM_FIELD_P5_TR_LIMIT, /* 19C */ + SMRAM_FIELD_P5_IDTR_ACCESS, /* 198 */ + SMRAM_FIELD_P5_IDTR_BASE, /* 194 */ + SMRAM_FIELD_P5_IDTR_LIMIT, /* 190 */ + SMRAM_FIELD_P5_GDTR_ACCESS, /* 18C */ + SMRAM_FIELD_P5_GDTR_BASE, /* 188 */ + SMRAM_FIELD_P5_GDTR_LIMIT, /* 184 */ + SMRAM_FIELD_P5_LDTR_ACCESS, /* 180 */ + SMRAM_FIELD_P5_LDTR_BASE, /* 17C */ + SMRAM_FIELD_P5_LDTR_LIMIT, /* 178 */ + SMRAM_FIELD_P5_GS_ACCESS, /* 174 */ + SMRAM_FIELD_P5_GS_BASE, /* 170 */ + SMRAM_FIELD_P5_GS_LIMIT, /* 16C */ + SMRAM_FIELD_P5_FS_ACCESS, /* 168 */ + SMRAM_FIELD_P5_FS_BASE, /* 164 */ + SMRAM_FIELD_P5_FS_LIMIT, /* 160 */ + SMRAM_FIELD_P5_DS_ACCESS, /* 15C */ + SMRAM_FIELD_P5_DS_BASE, /* 158 */ + SMRAM_FIELD_P5_DS_LIMIT, /* 154 */ + SMRAM_FIELD_P5_SS_ACCESS, /* 150 */ + SMRAM_FIELD_P5_SS_BASE, /* 14C */ + SMRAM_FIELD_P5_SS_LIMIT, /* 148 */ + SMRAM_FIELD_P5_CS_ACCESS, /* 144 */ + SMRAM_FIELD_P5_CS_BASE, /* 140 */ + SMRAM_FIELD_P5_CS_LIMIT, /* 13C */ + SMRAM_FIELD_P5_ES_ACCESS, /* 138 */ + SMRAM_FIELD_P5_ES_BASE, /* 134 */ + SMRAM_FIELD_P5_ES_LIMIT, /* 130 */ + SMRAM_FIELD_P5_UNWRITTEN_1, /* 12C */ + SMRAM_FIELD_P5_CR4, /* 128 */ + SMRAM_FIELD_P5_ALTERNATE_DR6, /* 124 */ + SMRAM_FIELD_P5_RESERVED_1, /* 120 */ + SMRAM_FIELD_P5_RESERVED_2, /* 11C */ + SMRAM_FIELD_P5_RESERVED_3, /* 118 */ + SMRAM_FIELD_P5_RESERVED_4, /* 114 */ + SMRAM_FIELD_P5_IO_RESTART_EIP, /* 110 */ + SMRAM_FIELD_P5_IO_RESTART_ESI, /* 10C */ + SMRAM_FIELD_P5_IO_RESTART_ECX, /* 108 */ + SMRAM_FIELD_P5_IO_RESTART_EDI, /* 104 */ + SMRAM_FIELD_P5_AUTOHALT_RESTART, /* 100 */ + SMRAM_FIELD_P5_SMM_REVISION_ID, /* 0FC */ + SMRAM_FIELD_P5_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_AM486_CR2, /* 0F4 */ + SMRAM_FIELD_AM486_DR0, /* 0F0 */ + SMRAM_FIELD_AM486_DR1, /* 0EC */ + SMRAM_FIELD_AM486_DR2, /* 0E8 */ + SMRAM_FIELD_AM486_DR3, /* 0E4 */ SMRAM_FIELD_P5_LAST }; enum SMMRAM_Fields_P6 { - SMRAM_FIELD_P6_CR0 = 0, /* 1FC */ - SMRAM_FIELD_P6_CR3, /* 1F8 */ - SMRAM_FIELD_P6_EFLAGS, /* 1F4 */ - SMRAM_FIELD_P6_EIP, /* 1F0 */ - SMRAM_FIELD_P6_EDI, /* 1EC */ - SMRAM_FIELD_P6_ESI, /* 1E8 */ - SMRAM_FIELD_P6_EBP, /* 1E4 */ - SMRAM_FIELD_P6_ESP, /* 1E0 */ - SMRAM_FIELD_P6_EBX, /* 1DC */ - SMRAM_FIELD_P6_EDX, /* 1D8 */ - SMRAM_FIELD_P6_ECX, /* 1D4 */ - SMRAM_FIELD_P6_EAX, /* 1D0 */ - SMRAM_FIELD_P6_DR6, /* 1CC */ - SMRAM_FIELD_P6_DR7, /* 1C8 */ - SMRAM_FIELD_P6_TR_SELECTOR, /* 1C4 */ - SMRAM_FIELD_P6_LDTR_SELECTOR, /* 1C0 */ - SMRAM_FIELD_P6_GS_SELECTOR, /* 1BC */ - SMRAM_FIELD_P6_FS_SELECTOR, /* 1B8 */ - SMRAM_FIELD_P6_DS_SELECTOR, /* 1B4 */ - SMRAM_FIELD_P6_SS_SELECTOR, /* 1B0 */ - SMRAM_FIELD_P6_CS_SELECTOR, /* 1AC */ - SMRAM_FIELD_P6_ES_SELECTOR, /* 1A8 */ - SMRAM_FIELD_P6_SS_BASE, /* 1A4 */ - SMRAM_FIELD_P6_SS_LIMIT, /* 1A0 */ - SMRAM_FIELD_P6_SS_SELECTOR_AR, /* 19C */ - SMRAM_FIELD_P6_CS_BASE, /* 198 */ - SMRAM_FIELD_P6_CS_LIMIT, /* 194 */ - SMRAM_FIELD_P6_CS_SELECTOR_AR, /* 190 */ - SMRAM_FIELD_P6_ES_BASE, /* 18C */ - SMRAM_FIELD_P6_ES_LIMIT, /* 188 */ - SMRAM_FIELD_P6_ES_SELECTOR_AR, /* 184 */ - SMRAM_FIELD_P6_LDTR_BASE, /* 180 */ - SMRAM_FIELD_P6_LDTR_LIMIT, /* 17C */ - SMRAM_FIELD_P6_LDTR_SELECTOR_AR, /* 178 */ - SMRAM_FIELD_P6_GDTR_BASE, /* 174 */ - SMRAM_FIELD_P6_GDTR_LIMIT, /* 170 */ - SMRAM_FIELD_P6_GDTR_SELECTOR_AR, /* 16C */ - SMRAM_FIELD_P6_SREG_STATUS1, /* 168 */ - SMRAM_FIELD_P6_TR_BASE, /* 164 */ - SMRAM_FIELD_P6_TR_LIMIT, /* 160 */ - SMRAM_FIELD_P6_TR_SELECTOR_AR, /* 15C */ - SMRAM_FIELD_P6_IDTR_BASE, /* 158 */ - SMRAM_FIELD_P6_IDTR_LIMIT, /* 154 */ - SMRAM_FIELD_P6_IDTR_SELECTOR_AR, /* 150 */ - SMRAM_FIELD_P6_GS_BASE, /* 14C */ - SMRAM_FIELD_P6_GS_LIMIT, /* 148 */ - SMRAM_FIELD_P6_GS_SELECTOR_AR, /* 144 */ - SMRAM_FIELD_P6_FS_BASE, /* 140 */ - SMRAM_FIELD_P6_FS_LIMIT, /* 13C */ - SMRAM_FIELD_P6_FS_SELECTOR_AR, /* 138 */ - SMRAM_FIELD_P6_DS_BASE, /* 134 */ - SMRAM_FIELD_P6_DS_LIMIT, /* 130 */ - SMRAM_FIELD_P6_DS_SELECTOR_AR, /* 12C */ - SMRAM_FIELD_P6_SREG_STATUS0, /* 128 */ - SMRAM_FIELD_P6_ALTERNATIVE_DR6, /* 124 */ - SMRAM_FIELD_P6_CPL, /* 120 */ - SMRAM_FIELD_P6_SMM_STATUS, /* 11C */ - SMRAM_FIELD_P6_A20M, /* 118 */ - SMRAM_FIELD_P6_CR4, /* 114 */ - SMRAM_FIELD_P6_IO_RESTART_EIP, /* 110 */ - SMRAM_FIELD_P6_IO_RESTART_ESI, /* 10C */ - SMRAM_FIELD_P6_IO_RESTART_ECX, /* 108 */ - SMRAM_FIELD_P6_IO_RESTART_EDI, /* 104 */ - SMRAM_FIELD_P6_AUTOHALT_RESTART, /* 100 */ - SMRAM_FIELD_P6_SMM_REVISION_ID, /* 0FC */ - SMRAM_FIELD_P6_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_P6_CR0 = 0, /* 1FC */ + SMRAM_FIELD_P6_CR3, /* 1F8 */ + SMRAM_FIELD_P6_EFLAGS, /* 1F4 */ + SMRAM_FIELD_P6_EIP, /* 1F0 */ + SMRAM_FIELD_P6_EDI, /* 1EC */ + SMRAM_FIELD_P6_ESI, /* 1E8 */ + SMRAM_FIELD_P6_EBP, /* 1E4 */ + SMRAM_FIELD_P6_ESP, /* 1E0 */ + SMRAM_FIELD_P6_EBX, /* 1DC */ + SMRAM_FIELD_P6_EDX, /* 1D8 */ + SMRAM_FIELD_P6_ECX, /* 1D4 */ + SMRAM_FIELD_P6_EAX, /* 1D0 */ + SMRAM_FIELD_P6_DR6, /* 1CC */ + SMRAM_FIELD_P6_DR7, /* 1C8 */ + SMRAM_FIELD_P6_TR_SELECTOR, /* 1C4 */ + SMRAM_FIELD_P6_LDTR_SELECTOR, /* 1C0 */ + SMRAM_FIELD_P6_GS_SELECTOR, /* 1BC */ + SMRAM_FIELD_P6_FS_SELECTOR, /* 1B8 */ + SMRAM_FIELD_P6_DS_SELECTOR, /* 1B4 */ + SMRAM_FIELD_P6_SS_SELECTOR, /* 1B0 */ + SMRAM_FIELD_P6_CS_SELECTOR, /* 1AC */ + SMRAM_FIELD_P6_ES_SELECTOR, /* 1A8 */ + SMRAM_FIELD_P6_SS_BASE, /* 1A4 */ + SMRAM_FIELD_P6_SS_LIMIT, /* 1A0 */ + SMRAM_FIELD_P6_SS_SELECTOR_AR, /* 19C */ + SMRAM_FIELD_P6_CS_BASE, /* 198 */ + SMRAM_FIELD_P6_CS_LIMIT, /* 194 */ + SMRAM_FIELD_P6_CS_SELECTOR_AR, /* 190 */ + SMRAM_FIELD_P6_ES_BASE, /* 18C */ + SMRAM_FIELD_P6_ES_LIMIT, /* 188 */ + SMRAM_FIELD_P6_ES_SELECTOR_AR, /* 184 */ + SMRAM_FIELD_P6_LDTR_BASE, /* 180 */ + SMRAM_FIELD_P6_LDTR_LIMIT, /* 17C */ + SMRAM_FIELD_P6_LDTR_SELECTOR_AR, /* 178 */ + SMRAM_FIELD_P6_GDTR_BASE, /* 174 */ + SMRAM_FIELD_P6_GDTR_LIMIT, /* 170 */ + SMRAM_FIELD_P6_GDTR_SELECTOR_AR, /* 16C */ + SMRAM_FIELD_P6_SREG_STATUS1, /* 168 */ + SMRAM_FIELD_P6_TR_BASE, /* 164 */ + SMRAM_FIELD_P6_TR_LIMIT, /* 160 */ + SMRAM_FIELD_P6_TR_SELECTOR_AR, /* 15C */ + SMRAM_FIELD_P6_IDTR_BASE, /* 158 */ + SMRAM_FIELD_P6_IDTR_LIMIT, /* 154 */ + SMRAM_FIELD_P6_IDTR_SELECTOR_AR, /* 150 */ + SMRAM_FIELD_P6_GS_BASE, /* 14C */ + SMRAM_FIELD_P6_GS_LIMIT, /* 148 */ + SMRAM_FIELD_P6_GS_SELECTOR_AR, /* 144 */ + SMRAM_FIELD_P6_FS_BASE, /* 140 */ + SMRAM_FIELD_P6_FS_LIMIT, /* 13C */ + SMRAM_FIELD_P6_FS_SELECTOR_AR, /* 138 */ + SMRAM_FIELD_P6_DS_BASE, /* 134 */ + SMRAM_FIELD_P6_DS_LIMIT, /* 130 */ + SMRAM_FIELD_P6_DS_SELECTOR_AR, /* 12C */ + SMRAM_FIELD_P6_SREG_STATUS0, /* 128 */ + SMRAM_FIELD_P6_ALTERNATIVE_DR6, /* 124 */ + SMRAM_FIELD_P6_CPL, /* 120 */ + SMRAM_FIELD_P6_SMM_STATUS, /* 11C */ + SMRAM_FIELD_P6_A20M, /* 118 */ + SMRAM_FIELD_P6_CR4, /* 114 */ + SMRAM_FIELD_P6_IO_RESTART_EIP, /* 110 */ + SMRAM_FIELD_P6_IO_RESTART_ESI, /* 10C */ + SMRAM_FIELD_P6_IO_RESTART_ECX, /* 108 */ + SMRAM_FIELD_P6_IO_RESTART_EDI, /* 104 */ + SMRAM_FIELD_P6_AUTOHALT_RESTART, /* 100 */ + SMRAM_FIELD_P6_SMM_REVISION_ID, /* 0FC */ + SMRAM_FIELD_P6_SMBASE_OFFSET, /* 0F8 */ SMRAM_FIELD_P6_LAST }; enum SMMRAM_Fields_AMD_K { - SMRAM_FIELD_AMD_K_CR0 = 0, /* 1FC */ - SMRAM_FIELD_AMD_K_CR3, /* 1F8 */ - SMRAM_FIELD_AMD_K_EFLAGS, /* 1F4 */ - SMRAM_FIELD_AMD_K_EIP, /* 1F0 */ - SMRAM_FIELD_AMD_K_EDI, /* 1EC */ - SMRAM_FIELD_AMD_K_ESI, /* 1E8 */ - SMRAM_FIELD_AMD_K_EBP, /* 1E4 */ - SMRAM_FIELD_AMD_K_ESP, /* 1E0 */ - SMRAM_FIELD_AMD_K_EBX, /* 1DC */ - SMRAM_FIELD_AMD_K_EDX, /* 1D8 */ - SMRAM_FIELD_AMD_K_ECX, /* 1D4 */ - SMRAM_FIELD_AMD_K_EAX, /* 1D0 */ - SMRAM_FIELD_AMD_K_DR6, /* 1CC */ - SMRAM_FIELD_AMD_K_DR7, /* 1C8 */ - SMRAM_FIELD_AMD_K_TR_SELECTOR, /* 1C4 */ - SMRAM_FIELD_AMD_K_LDTR_SELECTOR, /* 1C0 */ - SMRAM_FIELD_AMD_K_GS_SELECTOR, /* 1BC */ - SMRAM_FIELD_AMD_K_FS_SELECTOR, /* 1B8 */ - SMRAM_FIELD_AMD_K_DS_SELECTOR, /* 1B4 */ - SMRAM_FIELD_AMD_K_SS_SELECTOR, /* 1B0 */ - SMRAM_FIELD_AMD_K_CS_SELECTOR, /* 1AC */ - SMRAM_FIELD_AMD_K_ES_SELECTOR, /* 1A8 */ - SMRAM_FIELD_AMD_K_IO_RESTART_DWORD, /* 1A4 */ - SMRAM_FIELD_AMD_K_RESERVED_1, /* 1A0 */ - SMRAM_FIELD_AMD_K_IO_RESTART_EIP, /* 19C */ - SMRAM_FIELD_AMD_K_RESERVED_2, /* 198 */ - SMRAM_FIELD_AMD_K_RESERVED_3, /* 194 */ - SMRAM_FIELD_AMD_K_IDTR_BASE, /* 190 */ - SMRAM_FIELD_AMD_K_IDTR_LIMIT, /* 18C */ - SMRAM_FIELD_AMD_K_GDTR_BASE, /* 188 */ - SMRAM_FIELD_AMD_K_GDTR_LIMIT, /* 184 */ - SMRAM_FIELD_AMD_K_TR_ACCESS, /* 180 */ - SMRAM_FIELD_AMD_K_TR_BASE, /* 17C */ - SMRAM_FIELD_AMD_K_TR_LIMIT, /* 178 */ - SMRAM_FIELD_AMD_K_LDTR_ACCESS, /* 174 - reserved on K6 */ - SMRAM_FIELD_AMD_K_LDTR_BASE, /* 170 */ - SMRAM_FIELD_AMD_K_LDTR_LIMIT, /* 16C */ - SMRAM_FIELD_AMD_K_GS_ACCESS, /* 168 */ - SMRAM_FIELD_AMD_K_GS_BASE, /* 164 */ - SMRAM_FIELD_AMD_K_GS_LIMIT, /* 160 */ - SMRAM_FIELD_AMD_K_FS_ACCESS, /* 15C */ - SMRAM_FIELD_AMD_K_FS_BASE, /* 158 */ - SMRAM_FIELD_AMD_K_FS_LIMIT, /* 154 */ - SMRAM_FIELD_AMD_K_DS_ACCESS, /* 150 */ - SMRAM_FIELD_AMD_K_DS_BASE, /* 14C */ - SMRAM_FIELD_AMD_K_DS_LIMIT, /* 148 */ - SMRAM_FIELD_AMD_K_SS_ACCESS, /* 144 */ - SMRAM_FIELD_AMD_K_SS_BASE, /* 140 */ - SMRAM_FIELD_AMD_K_SS_LIMIT, /* 13C */ - SMRAM_FIELD_AMD_K_CS_ACCESS, /* 138 */ - SMRAM_FIELD_AMD_K_CS_BASE, /* 134 */ - SMRAM_FIELD_AMD_K_CS_LIMIT, /* 130 */ - SMRAM_FIELD_AMD_K_ES_ACCESS, /* 12C */ - SMRAM_FIELD_AMD_K_ES_BASE, /* 128 */ - SMRAM_FIELD_AMD_K_ES_LIMIT, /* 124 */ - SMRAM_FIELD_AMD_K_RESERVED_4, /* 120 */ - SMRAM_FIELD_AMD_K_RESERVED_5, /* 11C */ - SMRAM_FIELD_AMD_K_RESERVED_6, /* 118 */ - SMRAM_FIELD_AMD_K_CR2, /* 114 */ - SMRAM_FIELD_AMD_K_CR4, /* 110 */ - SMRAM_FIELD_AMD_K_IO_RESTART_ESI, /* 10C */ - SMRAM_FIELD_AMD_K_IO_RESTART_ECX, /* 108 */ - SMRAM_FIELD_AMD_K_IO_RESTART_EDI, /* 104 */ - SMRAM_FIELD_AMD_K_AUTOHALT_RESTART, /* 100 */ - SMRAM_FIELD_AMD_K_SMM_REVISION_ID, /* 0FC */ - SMRAM_FIELD_AMD_K_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_AMD_K_CR0 = 0, /* 1FC */ + SMRAM_FIELD_AMD_K_CR3, /* 1F8 */ + SMRAM_FIELD_AMD_K_EFLAGS, /* 1F4 */ + SMRAM_FIELD_AMD_K_EIP, /* 1F0 */ + SMRAM_FIELD_AMD_K_EDI, /* 1EC */ + SMRAM_FIELD_AMD_K_ESI, /* 1E8 */ + SMRAM_FIELD_AMD_K_EBP, /* 1E4 */ + SMRAM_FIELD_AMD_K_ESP, /* 1E0 */ + SMRAM_FIELD_AMD_K_EBX, /* 1DC */ + SMRAM_FIELD_AMD_K_EDX, /* 1D8 */ + SMRAM_FIELD_AMD_K_ECX, /* 1D4 */ + SMRAM_FIELD_AMD_K_EAX, /* 1D0 */ + SMRAM_FIELD_AMD_K_DR6, /* 1CC */ + SMRAM_FIELD_AMD_K_DR7, /* 1C8 */ + SMRAM_FIELD_AMD_K_TR_SELECTOR, /* 1C4 */ + SMRAM_FIELD_AMD_K_LDTR_SELECTOR, /* 1C0 */ + SMRAM_FIELD_AMD_K_GS_SELECTOR, /* 1BC */ + SMRAM_FIELD_AMD_K_FS_SELECTOR, /* 1B8 */ + SMRAM_FIELD_AMD_K_DS_SELECTOR, /* 1B4 */ + SMRAM_FIELD_AMD_K_SS_SELECTOR, /* 1B0 */ + SMRAM_FIELD_AMD_K_CS_SELECTOR, /* 1AC */ + SMRAM_FIELD_AMD_K_ES_SELECTOR, /* 1A8 */ + SMRAM_FIELD_AMD_K_IO_RESTART_DWORD, /* 1A4 */ + SMRAM_FIELD_AMD_K_RESERVED_1, /* 1A0 */ + SMRAM_FIELD_AMD_K_IO_RESTART_EIP, /* 19C */ + SMRAM_FIELD_AMD_K_RESERVED_2, /* 198 */ + SMRAM_FIELD_AMD_K_RESERVED_3, /* 194 */ + SMRAM_FIELD_AMD_K_IDTR_BASE, /* 190 */ + SMRAM_FIELD_AMD_K_IDTR_LIMIT, /* 18C */ + SMRAM_FIELD_AMD_K_GDTR_BASE, /* 188 */ + SMRAM_FIELD_AMD_K_GDTR_LIMIT, /* 184 */ + SMRAM_FIELD_AMD_K_TR_ACCESS, /* 180 */ + SMRAM_FIELD_AMD_K_TR_BASE, /* 17C */ + SMRAM_FIELD_AMD_K_TR_LIMIT, /* 178 */ + SMRAM_FIELD_AMD_K_LDTR_ACCESS, /* 174 - reserved on K6 */ + SMRAM_FIELD_AMD_K_LDTR_BASE, /* 170 */ + SMRAM_FIELD_AMD_K_LDTR_LIMIT, /* 16C */ + SMRAM_FIELD_AMD_K_GS_ACCESS, /* 168 */ + SMRAM_FIELD_AMD_K_GS_BASE, /* 164 */ + SMRAM_FIELD_AMD_K_GS_LIMIT, /* 160 */ + SMRAM_FIELD_AMD_K_FS_ACCESS, /* 15C */ + SMRAM_FIELD_AMD_K_FS_BASE, /* 158 */ + SMRAM_FIELD_AMD_K_FS_LIMIT, /* 154 */ + SMRAM_FIELD_AMD_K_DS_ACCESS, /* 150 */ + SMRAM_FIELD_AMD_K_DS_BASE, /* 14C */ + SMRAM_FIELD_AMD_K_DS_LIMIT, /* 148 */ + SMRAM_FIELD_AMD_K_SS_ACCESS, /* 144 */ + SMRAM_FIELD_AMD_K_SS_BASE, /* 140 */ + SMRAM_FIELD_AMD_K_SS_LIMIT, /* 13C */ + SMRAM_FIELD_AMD_K_CS_ACCESS, /* 138 */ + SMRAM_FIELD_AMD_K_CS_BASE, /* 134 */ + SMRAM_FIELD_AMD_K_CS_LIMIT, /* 130 */ + SMRAM_FIELD_AMD_K_ES_ACCESS, /* 12C */ + SMRAM_FIELD_AMD_K_ES_BASE, /* 128 */ + SMRAM_FIELD_AMD_K_ES_LIMIT, /* 124 */ + SMRAM_FIELD_AMD_K_RESERVED_4, /* 120 */ + SMRAM_FIELD_AMD_K_RESERVED_5, /* 11C */ + SMRAM_FIELD_AMD_K_RESERVED_6, /* 118 */ + SMRAM_FIELD_AMD_K_CR2, /* 114 */ + SMRAM_FIELD_AMD_K_CR4, /* 110 */ + SMRAM_FIELD_AMD_K_IO_RESTART_ESI, /* 10C */ + SMRAM_FIELD_AMD_K_IO_RESTART_ECX, /* 108 */ + SMRAM_FIELD_AMD_K_IO_RESTART_EDI, /* 104 */ + SMRAM_FIELD_AMD_K_AUTOHALT_RESTART, /* 100 */ + SMRAM_FIELD_AMD_K_SMM_REVISION_ID, /* 0FC */ + SMRAM_FIELD_AMD_K_SMBASE_OFFSET, /* 0F8 */ SMRAM_FIELD_AMD_K_LAST }; - #ifdef ENABLE_386_COMMON_LOG int x386_common_do_log = ENABLE_386_COMMON_LOG; - void x386_common_log(const char *fmt, ...) { va_list ap; if (x386_common_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x386_common_log(fmt, ...) +# define x386_common_log(fmt, ...) #endif - static __inline void set_stack32(int s) { - if ((cr0 & 1) && ! (cpu_state.eflags & VM_FLAG)) - stack32 = s; + if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG)) + stack32 = s; else - stack32 = 0; + stack32 = 0; if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; + cpu_cur_status |= CPU_STATUS_STACK32; else - cpu_cur_status &= ~CPU_STATUS_STACK32; + cpu_cur_status &= ~CPU_STATUS_STACK32; } - static __inline void set_use32(int u) { - if ((cr0 & 1) && ! (cpu_state.eflags & VM_FLAG)) - use32 = u ? 0x300 : 0; + if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG)) + use32 = u ? 0x300 : 0; else - use32 = 0; + use32 = 0; if (use32) - cpu_cur_status |= CPU_STATUS_USE32; + cpu_cur_status |= CPU_STATUS_USE32; else - cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_cur_status &= ~CPU_STATUS_USE32; } - static void smm_seg_load(x86seg *s) { if (!is386) - s->base &= 0x00ffffff; + s->base &= 0x00ffffff; if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) { - /* Expand down. */ - s->limit_high = s->limit; - s->limit_low = 0; + /* Expand down. */ + s->limit_high = s->limit; + s->limit_low = 0; } else { - s->limit_high = (s->ar_high & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; + s->limit_high = (s->ar_high & 0x40) ? 0xffffffff : 0xffff; + s->limit_low = s->limit + 1; } if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG)) - s->checked = s->seg ? 1 : 0; + s->checked = s->seg ? 1 : 0; else - s->checked = 1; + s->checked = 1; if (s == &cpu_state.seg_cs) - set_use32(s->ar_high & 0x40); + set_use32(s->ar_high & 0x40); if (s == &cpu_state.seg_ds) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &cpu_state.seg_ss) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - set_stack32((s->ar_high & 0x40) ? 1 : 0); + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + set_stack32((s->ar_high & 0x40) ? 1 : 0); } } - static void smram_save_state_p5(uint32_t *saved_state, int in_hlt) { int n = 0; saved_state[SMRAM_FIELD_P5_SMM_REVISION_ID] = SMM_REVISION_ID; - saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase; + saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase; for (n = 0; n < 8; n++) - saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l; + saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l; if (in_hlt) - saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 1; + saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 1; else - saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 0; + saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 0; saved_state[SMRAM_FIELD_P5_EIP] = cpu_state.pc; @@ -427,376 +416,367 @@ smram_save_state_p5(uint32_t *saved_state, int in_hlt) /* TR */ saved_state[SMRAM_FIELD_P5_TR_SELECTOR] = tr.seg; - saved_state[SMRAM_FIELD_P5_TR_BASE] = tr.base; - saved_state[SMRAM_FIELD_P5_TR_LIMIT] = tr.limit; - saved_state[SMRAM_FIELD_P5_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); + saved_state[SMRAM_FIELD_P5_TR_BASE] = tr.base; + saved_state[SMRAM_FIELD_P5_TR_LIMIT] = tr.limit; + saved_state[SMRAM_FIELD_P5_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); /* LDTR */ saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR] = ldt.seg; - saved_state[SMRAM_FIELD_P5_LDTR_BASE] = ldt.base; - saved_state[SMRAM_FIELD_P5_LDTR_LIMIT] = ldt.limit; - saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); + saved_state[SMRAM_FIELD_P5_LDTR_BASE] = ldt.base; + saved_state[SMRAM_FIELD_P5_LDTR_LIMIT] = ldt.limit; + saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); /* IDTR */ - saved_state[SMRAM_FIELD_P5_IDTR_BASE] = idt.base; - saved_state[SMRAM_FIELD_P5_IDTR_LIMIT] = idt.limit; + saved_state[SMRAM_FIELD_P5_IDTR_BASE] = idt.base; + saved_state[SMRAM_FIELD_P5_IDTR_LIMIT] = idt.limit; saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] = (idt.ar_high << 16) | (idt.access << 8); /* GDTR */ - saved_state[SMRAM_FIELD_P5_GDTR_BASE] = gdt.base; - saved_state[SMRAM_FIELD_P5_GDTR_LIMIT] = gdt.limit; + saved_state[SMRAM_FIELD_P5_GDTR_BASE] = gdt.base; + saved_state[SMRAM_FIELD_P5_GDTR_LIMIT] = gdt.limit; saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] = (gdt.ar_high << 16) | (gdt.access << 8); /* ES */ saved_state[SMRAM_FIELD_P5_ES_SELECTOR] = cpu_state.seg_es.seg; - saved_state[SMRAM_FIELD_P5_ES_BASE] = cpu_state.seg_es.base; - saved_state[SMRAM_FIELD_P5_ES_LIMIT] = cpu_state.seg_es.limit; - saved_state[SMRAM_FIELD_P5_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); + saved_state[SMRAM_FIELD_P5_ES_BASE] = cpu_state.seg_es.base; + saved_state[SMRAM_FIELD_P5_ES_LIMIT] = cpu_state.seg_es.limit; + saved_state[SMRAM_FIELD_P5_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); /* CS */ saved_state[SMRAM_FIELD_P5_CS_SELECTOR] = cpu_state.seg_cs.seg; - saved_state[SMRAM_FIELD_P5_CS_BASE] = cpu_state.seg_cs.base; - saved_state[SMRAM_FIELD_P5_CS_LIMIT] = cpu_state.seg_cs.limit; - saved_state[SMRAM_FIELD_P5_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); + saved_state[SMRAM_FIELD_P5_CS_BASE] = cpu_state.seg_cs.base; + saved_state[SMRAM_FIELD_P5_CS_LIMIT] = cpu_state.seg_cs.limit; + saved_state[SMRAM_FIELD_P5_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); /* DS */ saved_state[SMRAM_FIELD_P5_DS_SELECTOR] = cpu_state.seg_ds.seg; - saved_state[SMRAM_FIELD_P5_DS_BASE] = cpu_state.seg_ds.base; - saved_state[SMRAM_FIELD_P5_DS_LIMIT] = cpu_state.seg_ds.limit; - saved_state[SMRAM_FIELD_P5_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); + saved_state[SMRAM_FIELD_P5_DS_BASE] = cpu_state.seg_ds.base; + saved_state[SMRAM_FIELD_P5_DS_LIMIT] = cpu_state.seg_ds.limit; + saved_state[SMRAM_FIELD_P5_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); /* SS */ saved_state[SMRAM_FIELD_P5_SS_SELECTOR] = cpu_state.seg_ss.seg; - saved_state[SMRAM_FIELD_P5_SS_BASE] = cpu_state.seg_ss.base; - saved_state[SMRAM_FIELD_P5_SS_LIMIT] = cpu_state.seg_ss.limit; - saved_state[SMRAM_FIELD_P5_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); + saved_state[SMRAM_FIELD_P5_SS_BASE] = cpu_state.seg_ss.base; + saved_state[SMRAM_FIELD_P5_SS_LIMIT] = cpu_state.seg_ss.limit; + saved_state[SMRAM_FIELD_P5_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); /* FS */ saved_state[SMRAM_FIELD_P5_FS_SELECTOR] = cpu_state.seg_fs.seg; - saved_state[SMRAM_FIELD_P5_FS_BASE] = cpu_state.seg_fs.base; - saved_state[SMRAM_FIELD_P5_FS_LIMIT] = cpu_state.seg_fs.limit; - saved_state[SMRAM_FIELD_P5_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); + saved_state[SMRAM_FIELD_P5_FS_BASE] = cpu_state.seg_fs.base; + saved_state[SMRAM_FIELD_P5_FS_LIMIT] = cpu_state.seg_fs.limit; + saved_state[SMRAM_FIELD_P5_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); /* GS */ saved_state[SMRAM_FIELD_P5_GS_SELECTOR] = cpu_state.seg_gs.seg; - saved_state[SMRAM_FIELD_P5_GS_BASE] = cpu_state.seg_gs.base; - saved_state[SMRAM_FIELD_P5_GS_LIMIT] = cpu_state.seg_gs.limit; - saved_state[SMRAM_FIELD_P5_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); + saved_state[SMRAM_FIELD_P5_GS_BASE] = cpu_state.seg_gs.base; + saved_state[SMRAM_FIELD_P5_GS_LIMIT] = cpu_state.seg_gs.limit; + saved_state[SMRAM_FIELD_P5_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); /* Am486/5x86 stuff */ if (!is_pentium) { - saved_state[SMRAM_FIELD_AM486_CR2] = cr2; - saved_state[SMRAM_FIELD_AM486_DR0] = dr[0]; - saved_state[SMRAM_FIELD_AM486_DR1] = dr[1]; - saved_state[SMRAM_FIELD_AM486_DR2] = dr[2]; - saved_state[SMRAM_FIELD_AM486_DR3] = dr[3]; + saved_state[SMRAM_FIELD_AM486_CR2] = cr2; + saved_state[SMRAM_FIELD_AM486_DR0] = dr[0]; + saved_state[SMRAM_FIELD_AM486_DR1] = dr[1]; + saved_state[SMRAM_FIELD_AM486_DR2] = dr[2]; + saved_state[SMRAM_FIELD_AM486_DR3] = dr[3]; } } - static void smram_restore_state_p5(uint32_t *saved_state) { int n = 0; for (n = 0; n < 8; n++) - cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n]; + cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n]; if (saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] & 0xffff) - cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP] - 1; + cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP] - 1; else - cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP]; + cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP]; cpu_state.eflags = saved_state[SMRAM_FIELD_P5_EFLAGS] >> 16; - cpu_state.flags = saved_state[SMRAM_FIELD_P5_EFLAGS] & 0xffff; + cpu_state.flags = saved_state[SMRAM_FIELD_P5_EFLAGS] & 0xffff; - cr0 = saved_state[SMRAM_FIELD_P5_CR0]; - cr3 = saved_state[SMRAM_FIELD_P5_CR3]; - cr4 = saved_state[SMRAM_FIELD_P5_CR4]; + cr0 = saved_state[SMRAM_FIELD_P5_CR0]; + cr3 = saved_state[SMRAM_FIELD_P5_CR3]; + cr4 = saved_state[SMRAM_FIELD_P5_CR4]; dr[6] = saved_state[SMRAM_FIELD_P5_DR6]; dr[7] = saved_state[SMRAM_FIELD_P5_DR7]; /* TR */ - tr.seg = saved_state[SMRAM_FIELD_P5_TR_SELECTOR]; - tr.base = saved_state[SMRAM_FIELD_P5_TR_BASE]; - tr.limit = saved_state[SMRAM_FIELD_P5_TR_LIMIT]; - tr.access = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 8) & 0xff; + tr.seg = saved_state[SMRAM_FIELD_P5_TR_SELECTOR]; + tr.base = saved_state[SMRAM_FIELD_P5_TR_BASE]; + tr.limit = saved_state[SMRAM_FIELD_P5_TR_LIMIT]; + tr.access = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 8) & 0xff; tr.ar_high = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 16) & 0xff; smm_seg_load(&tr); /* LDTR */ - ldt.seg = saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR]; - ldt.base = saved_state[SMRAM_FIELD_P5_LDTR_BASE]; - ldt.limit = saved_state[SMRAM_FIELD_P5_LDTR_LIMIT]; - ldt.access = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 8) & 0xff; + ldt.seg = saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR]; + ldt.base = saved_state[SMRAM_FIELD_P5_LDTR_BASE]; + ldt.limit = saved_state[SMRAM_FIELD_P5_LDTR_LIMIT]; + ldt.access = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 8) & 0xff; ldt.ar_high = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 16) & 0xff; smm_seg_load(&ldt); /* IDTR */ - idt.base = saved_state[SMRAM_FIELD_P5_IDTR_BASE]; - idt.limit = saved_state[SMRAM_FIELD_P5_IDTR_LIMIT]; - idt.access = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 8) & 0xff; + idt.base = saved_state[SMRAM_FIELD_P5_IDTR_BASE]; + idt.limit = saved_state[SMRAM_FIELD_P5_IDTR_LIMIT]; + idt.access = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 8) & 0xff; idt.ar_high = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 16) & 0xff; /* GDTR */ - gdt.base = saved_state[SMRAM_FIELD_P5_GDTR_BASE]; - gdt.limit = saved_state[SMRAM_FIELD_P5_GDTR_LIMIT]; - gdt.access = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 8) & 0xff; + gdt.base = saved_state[SMRAM_FIELD_P5_GDTR_BASE]; + gdt.limit = saved_state[SMRAM_FIELD_P5_GDTR_LIMIT]; + gdt.access = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 8) & 0xff; gdt.ar_high = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 16) & 0xff; /* ES */ - cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P5_ES_SELECTOR]; - cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P5_ES_BASE]; - cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P5_ES_LIMIT]; - cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 8) & 0xff; + cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P5_ES_SELECTOR]; + cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P5_ES_BASE]; + cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P5_ES_LIMIT]; + cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 8) & 0xff; cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_es); /* CS */ - cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P5_CS_SELECTOR]; - cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P5_CS_BASE]; - cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P5_CS_LIMIT]; - cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 8) & 0xff; + cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P5_CS_SELECTOR]; + cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P5_CS_BASE]; + cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P5_CS_LIMIT]; + cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 8) & 0xff; cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_cs); /* DS */ - cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P5_DS_SELECTOR]; - cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P5_DS_BASE]; - cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P5_DS_LIMIT]; - cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 8) & 0xff; + cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P5_DS_SELECTOR]; + cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P5_DS_BASE]; + cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P5_DS_LIMIT]; + cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 8) & 0xff; cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ds); /* SS */ - cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P5_SS_SELECTOR]; - cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P5_SS_BASE]; - cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P5_SS_LIMIT]; + cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P5_SS_SELECTOR]; + cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P5_SS_BASE]; + cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P5_SS_LIMIT]; cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P5_SS_ACCESS] >> 8) & 0xff; /* The actual CPL (DPL of CS) is overwritten with DPL of SS. */ - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_P5_SS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ss); /* FS */ - cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P5_FS_SELECTOR]; - cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P5_FS_BASE]; - cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P5_FS_LIMIT]; - cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 8) & 0xff; + cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P5_FS_SELECTOR]; + cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P5_FS_BASE]; + cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P5_FS_LIMIT]; + cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 8) & 0xff; cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_fs); /* GS */ - cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P5_GS_SELECTOR]; - cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P5_GS_BASE]; - cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P5_GS_LIMIT]; - cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 8) & 0xff; + cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P5_GS_SELECTOR]; + cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P5_GS_BASE]; + cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P5_GS_LIMIT]; + cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 8) & 0xff; cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_gs); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET]; /* Am486/5x86 stuff */ if (!is_pentium) { - cr2 = saved_state[SMRAM_FIELD_AM486_CR2]; - dr[0] = saved_state[SMRAM_FIELD_AM486_DR0]; - dr[1] = saved_state[SMRAM_FIELD_AM486_DR1]; - dr[2] = saved_state[SMRAM_FIELD_AM486_DR2]; - dr[3] = saved_state[SMRAM_FIELD_AM486_DR3]; + cr2 = saved_state[SMRAM_FIELD_AM486_CR2]; + dr[0] = saved_state[SMRAM_FIELD_AM486_DR0]; + dr[1] = saved_state[SMRAM_FIELD_AM486_DR1]; + dr[2] = saved_state[SMRAM_FIELD_AM486_DR2]; + dr[3] = saved_state[SMRAM_FIELD_AM486_DR3]; } } - static void smram_save_state_p6(uint32_t *saved_state, int in_hlt) { int n = 0; saved_state[SMRAM_FIELD_P6_SMM_REVISION_ID] = SMM_REVISION_ID; - saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase; + saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase; for (n = 0; n < 8; n++) - saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l; + saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l; if (in_hlt) - saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 1; + saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 1; else - saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 0; + saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 0; saved_state[SMRAM_FIELD_P6_EIP] = cpu_state.pc; saved_state[SMRAM_FIELD_P6_EFLAGS] = (cpu_state.eflags << 16) | (cpu_state.flags); - saved_state[SMRAM_FIELD_P6_CR0] = cr0; - saved_state[SMRAM_FIELD_P6_CR3] = cr3; - saved_state[SMRAM_FIELD_P6_CR4] = cr4; - saved_state[SMRAM_FIELD_P6_DR6] = dr[6]; - saved_state[SMRAM_FIELD_P6_DR7] = dr[7]; - saved_state[SMRAM_FIELD_P6_CPL] = CPL; + saved_state[SMRAM_FIELD_P6_CR0] = cr0; + saved_state[SMRAM_FIELD_P6_CR3] = cr3; + saved_state[SMRAM_FIELD_P6_CR4] = cr4; + saved_state[SMRAM_FIELD_P6_DR6] = dr[6]; + saved_state[SMRAM_FIELD_P6_DR7] = dr[7]; + saved_state[SMRAM_FIELD_P6_CPL] = CPL; saved_state[SMRAM_FIELD_P6_A20M] = !mem_a20_state; /* TR */ - saved_state[SMRAM_FIELD_P6_TR_SELECTOR] = tr.seg; - saved_state[SMRAM_FIELD_P6_TR_BASE] = tr.base; - saved_state[SMRAM_FIELD_P6_TR_LIMIT] = tr.limit; + saved_state[SMRAM_FIELD_P6_TR_SELECTOR] = tr.seg; + saved_state[SMRAM_FIELD_P6_TR_BASE] = tr.base; + saved_state[SMRAM_FIELD_P6_TR_LIMIT] = tr.limit; saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] = (tr.ar_high << 24) | (tr.access << 16) | tr.seg; /* LDTR */ - saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR] = ldt.seg; - saved_state[SMRAM_FIELD_P6_LDTR_BASE] = ldt.base; - saved_state[SMRAM_FIELD_P6_LDTR_LIMIT] = ldt.limit; + saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR] = ldt.seg; + saved_state[SMRAM_FIELD_P6_LDTR_BASE] = ldt.base; + saved_state[SMRAM_FIELD_P6_LDTR_LIMIT] = ldt.limit; saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] = (ldt.ar_high << 24) | (ldt.access << 16) | ldt.seg; /* IDTR */ - saved_state[SMRAM_FIELD_P6_IDTR_BASE] = idt.base; - saved_state[SMRAM_FIELD_P6_IDTR_LIMIT] = idt.limit; + saved_state[SMRAM_FIELD_P6_IDTR_BASE] = idt.base; + saved_state[SMRAM_FIELD_P6_IDTR_LIMIT] = idt.limit; saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] = (idt.ar_high << 24) | (idt.access << 16) | idt.seg; /* GDTR */ - saved_state[SMRAM_FIELD_P6_GDTR_BASE] = gdt.base; - saved_state[SMRAM_FIELD_P6_GDTR_LIMIT] = gdt.limit; + saved_state[SMRAM_FIELD_P6_GDTR_BASE] = gdt.base; + saved_state[SMRAM_FIELD_P6_GDTR_LIMIT] = gdt.limit; saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] = (gdt.ar_high << 24) | (gdt.access << 16) | gdt.seg; /* ES */ - saved_state[SMRAM_FIELD_P6_ES_SELECTOR] = cpu_state.seg_es.seg; - saved_state[SMRAM_FIELD_P6_ES_BASE] = cpu_state.seg_es.base; - saved_state[SMRAM_FIELD_P6_ES_LIMIT] = cpu_state.seg_es.limit; - saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] = - (cpu_state.seg_es.ar_high << 24) | (cpu_state.seg_es.access << 16) | cpu_state.seg_es.seg; + saved_state[SMRAM_FIELD_P6_ES_SELECTOR] = cpu_state.seg_es.seg; + saved_state[SMRAM_FIELD_P6_ES_BASE] = cpu_state.seg_es.base; + saved_state[SMRAM_FIELD_P6_ES_LIMIT] = cpu_state.seg_es.limit; + saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] = (cpu_state.seg_es.ar_high << 24) | (cpu_state.seg_es.access << 16) | cpu_state.seg_es.seg; /* CS */ - saved_state[SMRAM_FIELD_P6_CS_SELECTOR] = cpu_state.seg_cs.seg; - saved_state[SMRAM_FIELD_P6_CS_BASE] = cpu_state.seg_cs.base; - saved_state[SMRAM_FIELD_P6_CS_LIMIT] = cpu_state.seg_cs.limit; - saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] = - (cpu_state.seg_cs.ar_high << 24) | (cpu_state.seg_cs.access << 16) | cpu_state.seg_cs.seg; + saved_state[SMRAM_FIELD_P6_CS_SELECTOR] = cpu_state.seg_cs.seg; + saved_state[SMRAM_FIELD_P6_CS_BASE] = cpu_state.seg_cs.base; + saved_state[SMRAM_FIELD_P6_CS_LIMIT] = cpu_state.seg_cs.limit; + saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] = (cpu_state.seg_cs.ar_high << 24) | (cpu_state.seg_cs.access << 16) | cpu_state.seg_cs.seg; /* DS */ - saved_state[SMRAM_FIELD_P6_DS_SELECTOR] = cpu_state.seg_ds.seg; - saved_state[SMRAM_FIELD_P6_DS_BASE] = cpu_state.seg_ds.base; - saved_state[SMRAM_FIELD_P6_DS_LIMIT] = cpu_state.seg_ds.limit; - saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] = - (cpu_state.seg_ds.ar_high << 24) | (cpu_state.seg_ds.access << 16) | cpu_state.seg_ds.seg; + saved_state[SMRAM_FIELD_P6_DS_SELECTOR] = cpu_state.seg_ds.seg; + saved_state[SMRAM_FIELD_P6_DS_BASE] = cpu_state.seg_ds.base; + saved_state[SMRAM_FIELD_P6_DS_LIMIT] = cpu_state.seg_ds.limit; + saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] = (cpu_state.seg_ds.ar_high << 24) | (cpu_state.seg_ds.access << 16) | cpu_state.seg_ds.seg; /* SS */ - saved_state[SMRAM_FIELD_P6_SS_SELECTOR] = cpu_state.seg_ss.seg; - saved_state[SMRAM_FIELD_P6_SS_BASE] = cpu_state.seg_ss.base; - saved_state[SMRAM_FIELD_P6_SS_LIMIT] = cpu_state.seg_ss.limit; - saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] = - (cpu_state.seg_ss.ar_high << 24) | (cpu_state.seg_ss.access << 16) | cpu_state.seg_ss.seg; + saved_state[SMRAM_FIELD_P6_SS_SELECTOR] = cpu_state.seg_ss.seg; + saved_state[SMRAM_FIELD_P6_SS_BASE] = cpu_state.seg_ss.base; + saved_state[SMRAM_FIELD_P6_SS_LIMIT] = cpu_state.seg_ss.limit; + saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] = (cpu_state.seg_ss.ar_high << 24) | (cpu_state.seg_ss.access << 16) | cpu_state.seg_ss.seg; /* FS */ - saved_state[SMRAM_FIELD_P6_FS_SELECTOR] = cpu_state.seg_fs.seg; - saved_state[SMRAM_FIELD_P6_FS_BASE] = cpu_state.seg_fs.base; - saved_state[SMRAM_FIELD_P6_FS_LIMIT] = cpu_state.seg_fs.limit; - saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] = - (cpu_state.seg_fs.ar_high << 24) | (cpu_state.seg_fs.access << 16) | cpu_state.seg_fs.seg; + saved_state[SMRAM_FIELD_P6_FS_SELECTOR] = cpu_state.seg_fs.seg; + saved_state[SMRAM_FIELD_P6_FS_BASE] = cpu_state.seg_fs.base; + saved_state[SMRAM_FIELD_P6_FS_LIMIT] = cpu_state.seg_fs.limit; + saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] = (cpu_state.seg_fs.ar_high << 24) | (cpu_state.seg_fs.access << 16) | cpu_state.seg_fs.seg; /* GS */ - saved_state[SMRAM_FIELD_P6_GS_SELECTOR] = cpu_state.seg_gs.seg; - saved_state[SMRAM_FIELD_P6_GS_BASE] = cpu_state.seg_gs.base; - saved_state[SMRAM_FIELD_P6_GS_LIMIT] = cpu_state.seg_gs.limit; - saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] = - (cpu_state.seg_gs.ar_high << 24) | (cpu_state.seg_gs.access << 16) | cpu_state.seg_gs.seg; + saved_state[SMRAM_FIELD_P6_GS_SELECTOR] = cpu_state.seg_gs.seg; + saved_state[SMRAM_FIELD_P6_GS_BASE] = cpu_state.seg_gs.base; + saved_state[SMRAM_FIELD_P6_GS_LIMIT] = cpu_state.seg_gs.limit; + saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] = (cpu_state.seg_gs.ar_high << 24) | (cpu_state.seg_gs.access << 16) | cpu_state.seg_gs.seg; } - static void smram_restore_state_p6(uint32_t *saved_state) { int n = 0; for (n = 0; n < 8; n++) - cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n]; + cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n]; if (saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] & 0xffff) - cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP] - 1; + cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP] - 1; else - cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP]; + cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP]; cpu_state.eflags = saved_state[SMRAM_FIELD_P6_EFLAGS] >> 16; - cpu_state.flags = saved_state[SMRAM_FIELD_P6_EFLAGS] & 0xffff; + cpu_state.flags = saved_state[SMRAM_FIELD_P6_EFLAGS] & 0xffff; - cr0 = saved_state[SMRAM_FIELD_P6_CR0]; - cr3 = saved_state[SMRAM_FIELD_P6_CR3]; - cr4 = saved_state[SMRAM_FIELD_P6_CR4]; + cr0 = saved_state[SMRAM_FIELD_P6_CR0]; + cr3 = saved_state[SMRAM_FIELD_P6_CR3]; + cr4 = saved_state[SMRAM_FIELD_P6_CR4]; dr[6] = saved_state[SMRAM_FIELD_P6_DR6]; dr[7] = saved_state[SMRAM_FIELD_P6_DR7]; /* TR */ - tr.seg = saved_state[SMRAM_FIELD_P6_TR_SELECTOR]; - tr.base = saved_state[SMRAM_FIELD_P6_TR_BASE]; - tr.limit = saved_state[SMRAM_FIELD_P6_TR_LIMIT]; - tr.access = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 16) & 0xff; + tr.seg = saved_state[SMRAM_FIELD_P6_TR_SELECTOR]; + tr.base = saved_state[SMRAM_FIELD_P6_TR_BASE]; + tr.limit = saved_state[SMRAM_FIELD_P6_TR_LIMIT]; + tr.access = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 16) & 0xff; tr.ar_high = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&tr); /* LDTR */ - ldt.seg = saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR]; - ldt.base = saved_state[SMRAM_FIELD_P6_LDTR_BASE]; - ldt.limit = saved_state[SMRAM_FIELD_P6_LDTR_LIMIT]; - ldt.access = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 16) & 0xff; + ldt.seg = saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR]; + ldt.base = saved_state[SMRAM_FIELD_P6_LDTR_BASE]; + ldt.limit = saved_state[SMRAM_FIELD_P6_LDTR_LIMIT]; + ldt.access = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 16) & 0xff; ldt.ar_high = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&ldt); /* IDTR */ - idt.base = saved_state[SMRAM_FIELD_P6_IDTR_BASE]; - idt.limit = saved_state[SMRAM_FIELD_P6_IDTR_LIMIT]; - idt.access = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 16) & 0xff; + idt.base = saved_state[SMRAM_FIELD_P6_IDTR_BASE]; + idt.limit = saved_state[SMRAM_FIELD_P6_IDTR_LIMIT]; + idt.access = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 16) & 0xff; idt.ar_high = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 24) & 0xff; /* GDTR */ - gdt.base = saved_state[SMRAM_FIELD_P6_GDTR_BASE]; - gdt.limit = saved_state[SMRAM_FIELD_P6_GDTR_LIMIT]; - gdt.access = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 16) & 0xff; + gdt.base = saved_state[SMRAM_FIELD_P6_GDTR_BASE]; + gdt.limit = saved_state[SMRAM_FIELD_P6_GDTR_LIMIT]; + gdt.access = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 16) & 0xff; gdt.ar_high = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 24) & 0xff; /* ES */ - cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P6_ES_SELECTOR]; - cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P6_ES_BASE]; - cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P6_ES_LIMIT]; - cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P6_ES_SELECTOR]; + cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P6_ES_BASE]; + cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P6_ES_LIMIT]; + cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_es); /* CS */ - cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P6_CS_SELECTOR]; - cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P6_CS_BASE]; - cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P6_CS_LIMIT]; - cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P6_CS_SELECTOR]; + cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P6_CS_BASE]; + cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P6_CS_LIMIT]; + cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_cs); cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((saved_state[SMRAM_FIELD_P6_CPL] & 0x03) << 5); /* DS */ - cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P6_DS_SELECTOR]; - cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P6_DS_BASE]; - cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P6_DS_LIMIT]; - cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P6_DS_SELECTOR]; + cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P6_DS_BASE]; + cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P6_DS_LIMIT]; + cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_ds); /* SS */ - cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P6_SS_SELECTOR]; - cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P6_SS_BASE]; - cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P6_SS_LIMIT]; - cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P6_SS_SELECTOR]; + cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P6_SS_BASE]; + cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P6_SS_LIMIT]; + cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_ss); /* FS */ - cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P6_FS_SELECTOR]; - cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P6_FS_BASE]; - cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P6_FS_LIMIT]; - cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P6_FS_SELECTOR]; + cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P6_FS_BASE]; + cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P6_FS_LIMIT]; + cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_fs); /* GS */ - cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P6_GS_SELECTOR]; - cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P6_GS_BASE]; - cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P6_GS_LIMIT]; - cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P6_GS_SELECTOR]; + cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P6_GS_BASE]; + cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P6_GS_LIMIT]; + cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_gs); @@ -805,25 +785,24 @@ smram_restore_state_p6(uint32_t *saved_state) mem_a20_recalc(); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET]; } - static void smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) { int n = 0; saved_state[SMRAM_FIELD_AMD_K_SMM_REVISION_ID] = SMM_REVISION_ID; - saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase; + saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase; for (n = 0; n < 8; n++) - saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l; + saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l; if (in_hlt) - saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 1; + saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 1; else - saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 0; + saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 0; saved_state[SMRAM_FIELD_AMD_K_EIP] = cpu_state.pc; @@ -838,167 +817,165 @@ smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) /* TR */ saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR] = tr.seg; - saved_state[SMRAM_FIELD_AMD_K_TR_BASE] = tr.base; - saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT] = tr.limit; - saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); + saved_state[SMRAM_FIELD_AMD_K_TR_BASE] = tr.base; + saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT] = tr.limit; + saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); /* LDTR */ saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR] = ldt.seg; - saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE] = ldt.base; - saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT] = ldt.limit; + saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE] = ldt.base; + saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT] = ldt.limit; if (!is_k6) - saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); + saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); /* IDTR */ - saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE] = idt.base; + saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE] = idt.base; saved_state[SMRAM_FIELD_AMD_K_IDTR_LIMIT] = idt.limit; /* GDTR */ - saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE] = gdt.base; + saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE] = gdt.base; saved_state[SMRAM_FIELD_AMD_K_GDTR_LIMIT] = gdt.limit; /* ES */ saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR] = cpu_state.seg_es.seg; - saved_state[SMRAM_FIELD_AMD_K_ES_BASE] = cpu_state.seg_es.base; - saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT] = cpu_state.seg_es.limit; - saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); + saved_state[SMRAM_FIELD_AMD_K_ES_BASE] = cpu_state.seg_es.base; + saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT] = cpu_state.seg_es.limit; + saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); /* CS */ saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR] = cpu_state.seg_cs.seg; - saved_state[SMRAM_FIELD_AMD_K_CS_BASE] = cpu_state.seg_cs.base; - saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT] = cpu_state.seg_cs.limit; - saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); + saved_state[SMRAM_FIELD_AMD_K_CS_BASE] = cpu_state.seg_cs.base; + saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT] = cpu_state.seg_cs.limit; + saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); /* DS */ saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR] = cpu_state.seg_ds.seg; - saved_state[SMRAM_FIELD_AMD_K_DS_BASE] = cpu_state.seg_ds.base; - saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT] = cpu_state.seg_ds.limit; - saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); + saved_state[SMRAM_FIELD_AMD_K_DS_BASE] = cpu_state.seg_ds.base; + saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT] = cpu_state.seg_ds.limit; + saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); /* SS */ saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR] = cpu_state.seg_ss.seg; - saved_state[SMRAM_FIELD_AMD_K_SS_BASE] = cpu_state.seg_ss.base; - saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT] = cpu_state.seg_ss.limit; - saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); + saved_state[SMRAM_FIELD_AMD_K_SS_BASE] = cpu_state.seg_ss.base; + saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT] = cpu_state.seg_ss.limit; + saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); /* FS */ saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR] = cpu_state.seg_fs.seg; - saved_state[SMRAM_FIELD_AMD_K_FS_BASE] = cpu_state.seg_fs.base; - saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT] = cpu_state.seg_fs.limit; - saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); + saved_state[SMRAM_FIELD_AMD_K_FS_BASE] = cpu_state.seg_fs.base; + saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT] = cpu_state.seg_fs.limit; + saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); /* GS */ saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR] = cpu_state.seg_gs.seg; - saved_state[SMRAM_FIELD_AMD_K_GS_BASE] = cpu_state.seg_gs.base; - saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT] = cpu_state.seg_gs.limit; - saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); + saved_state[SMRAM_FIELD_AMD_K_GS_BASE] = cpu_state.seg_gs.base; + saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT] = cpu_state.seg_gs.limit; + saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); } - static void smram_restore_state_amd_k(uint32_t *saved_state) { int n = 0; for (n = 0; n < 8; n++) - cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n]; + cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n]; if (saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] & 0xffff) - cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP] - 1; + cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP] - 1; else - cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP]; + cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP]; cpu_state.eflags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] >> 16; - cpu_state.flags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] & 0xffff; + cpu_state.flags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] & 0xffff; - cr0 = saved_state[SMRAM_FIELD_AMD_K_CR0]; - cr2 = saved_state[SMRAM_FIELD_AMD_K_CR2]; - cr3 = saved_state[SMRAM_FIELD_AMD_K_CR3]; - cr4 = saved_state[SMRAM_FIELD_AMD_K_CR4]; + cr0 = saved_state[SMRAM_FIELD_AMD_K_CR0]; + cr2 = saved_state[SMRAM_FIELD_AMD_K_CR2]; + cr3 = saved_state[SMRAM_FIELD_AMD_K_CR3]; + cr4 = saved_state[SMRAM_FIELD_AMD_K_CR4]; dr[6] = saved_state[SMRAM_FIELD_AMD_K_DR6]; dr[7] = saved_state[SMRAM_FIELD_AMD_K_DR7]; /* TR */ - tr.seg = saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR]; - tr.base = saved_state[SMRAM_FIELD_AMD_K_TR_BASE]; - tr.limit = saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT]; - tr.access = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 8) & 0xff; + tr.seg = saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR]; + tr.base = saved_state[SMRAM_FIELD_AMD_K_TR_BASE]; + tr.limit = saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT]; + tr.access = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 8) & 0xff; tr.ar_high = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 16) & 0xff; smm_seg_load(&tr); /* LDTR */ - ldt.seg = saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR]; - ldt.base = saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE]; + ldt.seg = saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR]; + ldt.base = saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE]; ldt.limit = saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT]; if (!is_k6) { - ldt.access = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 8) & 0xff; - ldt.ar_high = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 16) & 0xff; + ldt.access = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 8) & 0xff; + ldt.ar_high = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 16) & 0xff; } smm_seg_load(&ldt); /* IDTR */ - idt.base = saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE]; + idt.base = saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE]; idt.limit = saved_state[SMRAM_FIELD_AMD_K_IDTR_LIMIT]; /* GDTR */ - gdt.base = saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE]; + gdt.base = saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE]; gdt.limit = saved_state[SMRAM_FIELD_AMD_K_GDTR_LIMIT]; /* ES */ - cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR]; - cpu_state.seg_es.base = saved_state[SMRAM_FIELD_AMD_K_ES_BASE]; - cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT]; - cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 8) & 0xff; + cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR]; + cpu_state.seg_es.base = saved_state[SMRAM_FIELD_AMD_K_ES_BASE]; + cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT]; + cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 8) & 0xff; cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_es); /* CS */ - cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR]; - cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_AMD_K_CS_BASE]; - cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT]; - cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 8) & 0xff; + cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR]; + cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_AMD_K_CS_BASE]; + cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT]; + cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 8) & 0xff; cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_cs); /* DS */ - cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR]; - cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_AMD_K_DS_BASE]; - cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT]; - cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 8) & 0xff; + cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR]; + cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_AMD_K_DS_BASE]; + cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT]; + cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 8) & 0xff; cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ds); /* SS */ - cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR]; - cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_AMD_K_SS_BASE]; - cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT]; + cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR]; + cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_AMD_K_SS_BASE]; + cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT]; cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] >> 8) & 0xff; /* The actual CPL (DPL of CS) is overwritten with DPL of SS. */ - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ss); /* FS */ - cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR]; - cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_AMD_K_FS_BASE]; - cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT]; - cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 8) & 0xff; + cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR]; + cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_AMD_K_FS_BASE]; + cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT]; + cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 8) & 0xff; cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_fs); /* GS */ - cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR]; - cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_AMD_K_GS_BASE]; - cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT]; - cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 8) & 0xff; + cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR]; + cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_AMD_K_GS_BASE]; + cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT]; + cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 8) & 0xff; cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_gs); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET]; } - static void smram_save_state_cyrix(uint32_t *saved_state, int in_hlt) { @@ -1011,18 +988,16 @@ smram_save_state_cyrix(uint32_t *saved_state, int in_hlt) saved_state[6] = 0x00000000; } - static void smram_restore_state_cyrix(uint32_t *saved_state) { - dr[7] = saved_state[0]; - cpu_state.flags = saved_state[1] & 0xffff; + dr[7] = saved_state[0]; + cpu_state.flags = saved_state[1] & 0xffff; cpu_state.eflags = saved_state[1] >> 16; - cr0 = saved_state[2]; - cpu_state.pc = saved_state[4]; + cr0 = saved_state[2]; + cpu_state.pc = saved_state[4]; } - void enter_smm(int in_hlt) { @@ -1031,39 +1006,39 @@ enter_smm(int in_hlt) /* If it's a CPU on which SMM is not supported, do nothing. */ if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cxsmm) - return; + return; x386_common_log("enter_smm(): smbase = %08X\n", smbase); x386_common_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, - cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); + cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, + cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); x386_common_log("DS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, - cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); + cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, + cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); x386_common_log("ES : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, - cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); + cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, + cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); x386_common_log("FS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, - cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); + cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, + cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); x386_common_log("GS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, - cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); + cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, + cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); x386_common_log("SS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, - cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); + cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, + cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); x386_common_log("TR : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); + tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); x386_common_log("LDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); + ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); x386_common_log("GDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); + gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); x386_common_log("IDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); + idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); x386_common_log("CR0 = %08X, CR3 = %08X, CR4 = %08X, DR6 = %08X, DR7 = %08X\n", cr0, cr3, cr4, dr[6], dr[7]); x386_common_log("EIP = %08X, EFLAGS = %04X%04X\n", cpu_state.pc, cpu_state.eflags, cpu_state.flags); x386_common_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n", - EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); + EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); flags_rebuild(); in_smm = 1; @@ -1071,24 +1046,24 @@ enter_smm(int in_hlt) smram_recalc_all(0); if (is_cxsmm) { - if (!(cyrix.smhr & SMHR_VALID)) - cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; - smram_state = cyrix.smhr & SMHR_ADDR_MASK; + if (!(cyrix.smhr & SMHR_VALID)) + cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; + smram_state = cyrix.smhr & SMHR_ADDR_MASK; } memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); - if (is_cxsmm) /* Cx6x86 */ - smram_save_state_cyrix(saved_state, in_hlt); - else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ - smram_save_state_p5(saved_state, in_hlt); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ - smram_save_state_amd_k(saved_state, in_hlt); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ - smram_save_state_p6(saved_state, in_hlt); + if (is_cxsmm) /* Cx6x86 */ + smram_save_state_cyrix(saved_state, in_hlt); + else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ + smram_save_state_p5(saved_state, in_hlt); + else if (is_k5 || is_k6) /* AMD K5 and K6 */ + smram_save_state_amd_k(saved_state, in_hlt); + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + smram_save_state_p6(saved_state, in_hlt); cr0 &= ~0x8000000d; - cpu_state.flags = 2; + cpu_state.flags = 2; cpu_state.eflags = 0; cr4 = 0; @@ -1096,87 +1071,87 @@ enter_smm(int in_hlt) dr[7] = 0x400; if (is_cxsmm) { - cpu_state.pc = 0x0000; - cpl_override = 1; - cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); - cpl_override = 0; - cpu_state.seg_cs.seg = (cyrix.arr[3].base >> 4); - cpu_state.seg_cs.base = cyrix.arr[3].base; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.access = 0x93; - cpu_state.seg_cs.ar_high = 0x80; - cpu_state.seg_cs.checked = 1; + cpu_state.pc = 0x0000; + cpl_override = 1; + cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + cpl_override = 0; + cpu_state.seg_cs.seg = (cyrix.arr[3].base >> 4); + cpu_state.seg_cs.base = cyrix.arr[3].base; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.ar_high = 0x80; + cpu_state.seg_cs.checked = 1; - smm_seg_load(&cpu_state.seg_cs); + smm_seg_load(&cpu_state.seg_cs); } else { - cpu_state.pc = 0x8000; - cpu_state.seg_ds.seg = 0x00000000; - cpu_state.seg_ds.base = 0x00000000; - cpu_state.seg_ds.limit = 0xffffffff; - cpu_state.seg_ds.access = 0x93; - cpu_state.seg_ds.ar_high = 0x80; + cpu_state.pc = 0x8000; + cpu_state.seg_ds.seg = 0x00000000; + cpu_state.seg_ds.base = 0x00000000; + cpu_state.seg_ds.limit = 0xffffffff; + cpu_state.seg_ds.access = 0x93; + cpu_state.seg_ds.ar_high = 0x80; - memcpy(&cpu_state.seg_es, &cpu_state.seg_ds, sizeof(x86seg)); - memcpy(&cpu_state.seg_ss, &cpu_state.seg_ds, sizeof(x86seg)); - memcpy(&cpu_state.seg_fs, &cpu_state.seg_ds, sizeof(x86seg)); - memcpy(&cpu_state.seg_gs, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_es, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_ss, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_fs, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_gs, &cpu_state.seg_ds, sizeof(x86seg)); - if (is_p6) - cpu_state.seg_cs.seg = (smbase >> 4); - else - cpu_state.seg_cs.seg = 0x3000; + if (is_p6) + cpu_state.seg_cs.seg = (smbase >> 4); + else + cpu_state.seg_cs.seg = 0x3000; - /* On Pentium, CS selector in SMM is always 3000, regardless of SMBASE. */ - cpu_state.seg_cs.base = smbase; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.access = 0x93; - cpu_state.seg_cs.ar_high = 0x80; - cpu_state.seg_cs.checked = 1; + /* On Pentium, CS selector in SMM is always 3000, regardless of SMBASE. */ + cpu_state.seg_cs.base = smbase; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.ar_high = 0x80; + cpu_state.seg_cs.checked = 1; - smm_seg_load(&cpu_state.seg_es); - smm_seg_load(&cpu_state.seg_cs); - smm_seg_load(&cpu_state.seg_ds); - smm_seg_load(&cpu_state.seg_ss); - smm_seg_load(&cpu_state.seg_fs); - smm_seg_load(&cpu_state.seg_gs); + smm_seg_load(&cpu_state.seg_es); + smm_seg_load(&cpu_state.seg_cs); + smm_seg_load(&cpu_state.seg_ds); + smm_seg_load(&cpu_state.seg_ss); + smm_seg_load(&cpu_state.seg_fs); + smm_seg_load(&cpu_state.seg_gs); } cpu_state.op32 = use32; cpl_override = 1; if (is_cxsmm) { - writememl(0, smram_state - 0x04, saved_state[0]); - writememl(0, smram_state - 0x08, saved_state[1]); - writememl(0, smram_state - 0x0c, saved_state[2]); - writememl(0, smram_state - 0x10, saved_state[3]); - writememl(0, smram_state - 0x14, saved_state[4]); - writememl(0, smram_state - 0x18, saved_state[5]); - writememl(0, smram_state - 0x24, saved_state[6]); + writememl(0, smram_state - 0x04, saved_state[0]); + writememl(0, smram_state - 0x08, saved_state[1]); + writememl(0, smram_state - 0x0c, saved_state[2]); + writememl(0, smram_state - 0x10, saved_state[3]); + writememl(0, smram_state - 0x14, saved_state[4]); + writememl(0, smram_state - 0x18, saved_state[5]); + writememl(0, smram_state - 0x24, saved_state[6]); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { - smram_state -= 4; - writememl(0, smram_state, saved_state[n]); - } + for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + smram_state -= 4; + writememl(0, smram_state, saved_state[n]); + } } cpl_override = 0; nmi_mask = 0; if (smi_latched) { - in_smm = 2; - smi_latched = 0; + in_smm = 2; + smi_latched = 0; } else - in_smm = 1; + in_smm = 1; smm_in_hlt = in_hlt; if (unmask_a20_in_smm) { - old_rammask = rammask; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - if (is6117) - rammask |= 0x3000000; + old_rammask = rammask; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + if (is6117) + rammask |= 0x3000000; - flushmmucache(); + flushmmucache(); } oldcpl = 0; @@ -1185,33 +1160,31 @@ enter_smm(int in_hlt) CPU_BLOCK_END(); } - void enter_smm_check(int in_hlt) { if ((in_smm == 0) && smi_line) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SMI while not in SMM\n"); + x386_common_log("SMI while not in SMM\n"); #endif - enter_smm(in_hlt); + enter_smm(in_hlt); } else if ((in_smm == 1) && smi_line) { - /* Mark this so that we don't latch more than one SMI. */ + /* Mark this so that we don't latch more than one SMI. */ #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SMI while in unlatched SMM\n"); + x386_common_log("SMI while in unlatched SMM\n"); #endif - smi_latched = 1; + smi_latched = 1; } else if ((in_smm == 2) && smi_line) { - /* Mark this so that we don't latch more than one SMI. */ + /* Mark this so that we don't latch more than one SMI. */ #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SMI while in latched SMM\n"); + x386_common_log("SMI while in latched SMM\n"); #endif } if (smi_line) - smi_line = 0; + smi_line = 0; } - void leave_smm(void) { @@ -1220,45 +1193,45 @@ leave_smm(void) /* If it's a CPU on which SMM is not supported (or not implemented in 86Box), do nothing. */ if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cxsmm) - return; + return; memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); cpl_override = 1; if (is_cxsmm) { - smram_state = cyrix.smhr & SMHR_ADDR_MASK; - saved_state[0] = readmeml(0, smram_state - 0x04); - saved_state[1] = readmeml(0, smram_state - 0x08); - saved_state[2] = readmeml(0, smram_state - 0x0c); - saved_state[3] = readmeml(0, smram_state - 0x10); - saved_state[4] = readmeml(0, smram_state - 0x14); - saved_state[5] = readmeml(0, smram_state - 0x18); - cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); - saved_state[6] = readmeml(0, smram_state - 0x24); + smram_state = cyrix.smhr & SMHR_ADDR_MASK; + saved_state[0] = readmeml(0, smram_state - 0x04); + saved_state[1] = readmeml(0, smram_state - 0x08); + saved_state[2] = readmeml(0, smram_state - 0x0c); + saved_state[3] = readmeml(0, smram_state - 0x10); + saved_state[4] = readmeml(0, smram_state - 0x14); + saved_state[5] = readmeml(0, smram_state - 0x18); + cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + saved_state[6] = readmeml(0, smram_state - 0x24); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { - smram_state -= 4; - saved_state[n] = readmeml(0, smram_state); - x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n); - } + for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + smram_state -= 4; + saved_state[n] = readmeml(0, smram_state); + x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n); + } } cpl_override = 0; if (unmask_a20_in_smm) { - rammask = old_rammask; + rammask = old_rammask; - flushmmucache(); + flushmmucache(); } x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]); - if (is_cxsmm) /* Cx6x86 */ - smram_restore_state_cyrix(saved_state); - else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ - smram_restore_state_p5(saved_state); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ - smram_restore_state_amd_k(saved_state); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ - smram_restore_state_p6(saved_state); + if (is_cxsmm) /* Cx6x86 */ + smram_restore_state_cyrix(saved_state); + else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ + smram_restore_state_p5(saved_state); + else if (is_k5 || is_k6) /* AMD K5 and K6 */ + smram_restore_state_amd_k(saved_state); + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + smram_restore_state_p6(saved_state); in_smm = 0; smram_recalc_all(1); @@ -1266,9 +1239,9 @@ leave_smm(void) cpu_386_flags_extract(); cpu_cur_status &= ~(CPU_STATUS_PMODE | CPU_STATUS_V86); if (cr0 & 1) { - cpu_cur_status |= CPU_STATUS_PMODE; - if (cpu_state.eflags & VM_FLAG) - cpu_cur_status |= CPU_STATUS_V86; + cpu_cur_status |= CPU_STATUS_PMODE; + if (cpu_state.eflags & VM_FLAG) + cpu_cur_status |= CPU_STATUS_V86; } nmi_mask = 1; @@ -1278,90 +1251,88 @@ leave_smm(void) CPU_BLOCK_END(); x386_common_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, - cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); + cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, + cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); x386_common_log("DS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, - cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); + cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, + cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); x386_common_log("ES : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, - cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); + cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, + cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); x386_common_log("FS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, - cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); + cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, + cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); x386_common_log("GS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, - cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); + cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, + cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); x386_common_log("SS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, - cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); + cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, + cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); x386_common_log("TR : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); + tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); x386_common_log("LDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); + ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); x386_common_log("GDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); + gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); x386_common_log("IDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); + idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); x386_common_log("CR0 = %08X, CR3 = %08X, CR4 = %08X, DR6 = %08X, DR7 = %08X\n", cr0, cr3, cr4, dr[6], dr[7]); x386_common_log("EIP = %08X, EFLAGS = %04X%04X\n", cpu_state.pc, cpu_state.eflags, cpu_state.flags); x386_common_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n", - EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); + EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); x386_common_log("leave_smm()\n"); } - void x86_int(int num) { uint32_t addr; flags_rebuild(); - cpu_state.pc=cpu_state.oldpc; + cpu_state.pc = cpu_state.oldpc; - if (msw&1) - pmodeint(num,0); + if (msw & 1) + pmodeint(num, 0); else { - addr = (num << 2) + idt.base; + addr = (num << 2) + idt.base; - if ((num << 2UL) + 3UL > idt.limit) { - if (idt.limit < 35) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); + if ((num << 2UL) + 3UL > idt.limit) { + if (idt.limit < 35) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); #ifdef ENABLE_386_COMMON_LOG - x386_common_log("Triple fault in real mode - reset\n"); + x386_common_log("Triple fault in real mode - reset\n"); #endif - } else - x86_int(8); - } else { - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - } + } else + x86_int(8); + } else { + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } } cycles -= 70; CPU_BLOCK_END(); } - void x86_int_sw(int num) { @@ -1370,42 +1341,41 @@ x86_int_sw(int num) flags_rebuild(); cycles -= timing_int; - if (msw&1) - pmodeint(num,1); + if (msw & 1) + pmodeint(num, 1); else { - addr = (num << 2) + idt.base; + addr = (num << 2) + idt.base; - if ((num << 2UL) + 3UL > idt.limit) - x86_int(0x0d); - else { - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - } + if ((num << 2UL) + 3UL > idt.limit) + x86_int(0x0d); + else { + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - cycles -= timing_int_rm; - } + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + cycles -= timing_int_rm; + } } trap = 0; CPU_BLOCK_END(); } - int x86_int_sw_rm(int num) { @@ -1415,23 +1385,23 @@ x86_int_sw_rm(int num) flags_rebuild(); cycles -= timing_int; - addr = num << 2; + addr = num << 2; new_pc = readmemw(0, addr); new_cs = readmemw(0, addr + 2); if (cpu_state.abrt) - return 1; + return 1; writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); if (cpu_state.abrt) - return 1; + return 1; writememw(ss, ((SP - 4) & 0xFFFF), CS); writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); if (cpu_state.abrt) - return 1; + return 1; SP -= 6; @@ -1450,49 +1420,47 @@ x86_int_sw_rm(int num) return 0; } - void -x86illegal() +x86illegal(void) { x86_int(6); } - int checkio(uint32_t port) { uint16_t t; - uint8_t d; + uint8_t d; cpl_override = 1; - t = readmemw(tr.base, 0x66); + t = readmemw(tr.base, 0x66); cpl_override = 0; if (cpu_state.abrt) - return 0; + return 0; if ((t + (port >> 3UL)) > tr.limit) - return 1; + return 1; cpl_override = 1; - d = readmembl(tr.base + t + (port >> 3)); + d = readmembl(tr.base + t + (port >> 3)); cpl_override = 0; return d & (1 << (port & 7)); } - #ifdef OLD_DIVEXCP -#define divexcp() { \ - x386_common_log("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ - x86_int(0); \ -} +# define divexcp() \ + { \ + x386_common_log("Divide exception at %04X(%06X):%04X\n", CS, cs, cpu_state.pc); \ + x86_int(0); \ + } #else -#define divexcp() { \ - x86de(NULL, 0); \ -} +# define divexcp() \ + { \ + x86de(NULL, 0); \ + } #endif - int divl(uint32_t val) { @@ -1500,18 +1468,18 @@ divl(uint32_t val) uint32_t rem, quo32; if (val == 0) { - divexcp(); - return 1; + divexcp(); + return 1; } - num = (((uint64_t) EDX) << 32) | EAX; - quo = num / val; - rem = num % val; - quo32=(uint32_t)(quo&0xFFFFFFFF); + num = (((uint64_t) EDX) << 32) | EAX; + quo = num / val; + rem = num % val; + quo32 = (uint32_t) (quo & 0xFFFFFFFF); if (quo != (uint64_t) quo32) { - divexcp(); - return 1; + divexcp(); + return 1; } EDX = rem; @@ -1520,26 +1488,25 @@ divl(uint32_t val) return 0; } - int idivl(int32_t val) { int64_t num, quo; int32_t rem, quo32; - if (val == 0) { - divexcp(); - return 1; + if (val == 0) { + divexcp(); + return 1; } - num = (((uint64_t) EDX) << 32) | EAX; - quo = num / val; - rem = num % val; + num = (((uint64_t) EDX) << 32) | EAX; + quo = num / val; + rem = num % val; quo32 = (int32_t) (quo & 0xFFFFFFFF); if (quo != (int64_t) quo32) { - divexcp(); - return 1; + divexcp(); + return 1; } EDX = rem; @@ -1548,21 +1515,18 @@ idivl(int32_t val) return 0; } - void -cpu_386_flags_extract() +cpu_386_flags_extract(void) { flags_extract(); } - void -cpu_386_flags_rebuild() +cpu_386_flags_rebuild(void) { flags_rebuild(); } - int sysenter(uint32_t fetchdat) { @@ -1572,18 +1536,18 @@ sysenter(uint32_t fetchdat) if (!(msw & 1)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSENTER: CPU not in protected mode"); + x386_common_log("SYSENTER: CPU not in protected mode"); #endif - x86gpf("SYSENTER: CPU not in protected mode", 0); - return cpu_state.abrt; + x86gpf("SYSENTER: CPU not in protected mode", 0); + return cpu_state.abrt; } if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSENTER: CS MSR is zero"); + x386_common_log("SYSENTER: CS MSR is zero"); #endif - x86gpf("SYSENTER: CS MSR is zero", 0); - return cpu_state.abrt; + x86gpf("SYSENTER: CS MSR is zero", 0); + return cpu_state.abrt; } #ifdef ENABLE_386_COMMON_LOG @@ -1602,33 +1566,33 @@ sysenter(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ESP = msr.sysenter_esp; - cpu_state.pc = msr.sysenter_eip; + ESP = msr.sysenter_esp; + cpu_state.pc = msr.sysenter_eip; - cpu_state.seg_cs.seg = (msr.sysenter_cs & 0xfffc); - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.seg = (msr.sysenter_cs & 0xfffc); + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0x9b; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 0; + cpu_state.seg_cs.access = 0x9b; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 0; - cpu_state.seg_ss.seg = ((msr.sysenter_cs + 8) & 0xfffc); - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.seg = ((msr.sysenter_cs + 8) & 0xfffc); + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0x93; - cpu_state.seg_ss.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0x93; + cpu_state.seg_ss.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86); - cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32/* | CPU_STATUS_PMODE*/); + cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 /* | CPU_STATUS_PMODE*/); set_use32(1); set_stack32(1); @@ -1645,7 +1609,6 @@ sysenter(uint32_t fetchdat) return 1; } - int sysexit(uint32_t fetchdat) { @@ -1655,26 +1618,26 @@ sysexit(uint32_t fetchdat) if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSEXIT: CS MSR is zero"); + x386_common_log("SYSEXIT: CS MSR is zero"); #endif - x86gpf("SYSEXIT: CS MSR is zero", 0); - return cpu_state.abrt; + x86gpf("SYSEXIT: CS MSR is zero", 0); + return cpu_state.abrt; } if (!(msw & 1)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSEXIT: CPU not in protected mode"); + x386_common_log("SYSEXIT: CPU not in protected mode"); #endif - x86gpf("SYSEXIT: CPU not in protected mode", 0); - return cpu_state.abrt; + x86gpf("SYSEXIT: CPU not in protected mode", 0); + return cpu_state.abrt; } if (CPL) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSEXIT: CPL not 0"); + x386_common_log("SYSEXIT: CPL not 0"); #endif - x86gpf("SYSEXIT: CPL not 0", 0); - return cpu_state.abrt; + x86gpf("SYSEXIT: CPL not 0", 0); + return cpu_state.abrt; } #ifdef ENABLE_386_COMMON_LOG @@ -1689,32 +1652,32 @@ sysexit(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ESP = ECX; - cpu_state.pc = EDX; + ESP = ECX; + cpu_state.pc = EDX; - cpu_state.seg_cs.seg = (((msr.sysenter_cs + 16) & 0xfffc) | 3); - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.seg = (((msr.sysenter_cs + 16) & 0xfffc) | 3); + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0xfb; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 3; + cpu_state.seg_cs.access = 0xfb; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 3; - cpu_state.seg_ss.seg = (((msr.sysenter_cs + 24) & 0xfffc) | 3); - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.seg = (((msr.sysenter_cs + 24) & 0xfffc) | 3); + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0xf3; - cpu_state.seg_ss.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0xf3; + cpu_state.seg_ss.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif - cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS/* | CPU_STATUS_V86*/); + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS /* | CPU_STATUS_V86*/); cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); flushmmucache_cr3(); set_use32(1); @@ -1733,7 +1696,6 @@ sysexit(uint32_t fetchdat) return 1; } - int syscall_op(uint32_t fetchdat) { @@ -1750,28 +1712,28 @@ syscall_op(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ECX = cpu_state.pc; + ECX = cpu_state.pc; /* CS */ - CS = AMD_SYSCALL_SB & 0xfffc; - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + CS = AMD_SYSCALL_SB & 0xfffc; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0x9b; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 0; + cpu_state.seg_cs.access = 0x9b; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 0; /* SS */ - SS = (AMD_SYSCALL_SB + 8) & 0xfffc; - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + SS = (AMD_SYSCALL_SB + 8) & 0xfffc; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0x93; - cpu_state.seg_ss.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0x93; + cpu_state.seg_ss.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif @@ -1786,7 +1748,6 @@ syscall_op(uint32_t fetchdat) return 1; } - int sysret(uint32_t fetchdat) { @@ -1796,10 +1757,10 @@ sysret(uint32_t fetchdat) if (CPL) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSRET: CPL not 0"); + x386_common_log("SYSRET: CPL not 0"); #endif - x86gpf("SYSRET: CPL not 0", 0); - return cpu_state.abrt; + x86gpf("SYSRET: CPL not 0", 0); + return cpu_state.abrt; } cpu_state.flags |= I_FLAG; @@ -1811,33 +1772,33 @@ sysret(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - cpu_state.pc = ECX; + cpu_state.pc = ECX; /* CS */ - CS = (AMD_SYSRET_SB & 0xfffc) | 3; - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + CS = (AMD_SYSRET_SB & 0xfffc) | 3; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0xfb; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 3; + cpu_state.seg_cs.access = 0xfb; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 3; /* SS */ - SS = ((AMD_SYSRET_SB + 8) & 0xfffc) | 3; - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + SS = ((AMD_SYSRET_SB + 8) & 0xfffc) | 3; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0xf3; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0xf3; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif - cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS/* | CPU_STATUS_V86*/); + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS /* | CPU_STATUS_V86*/); cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); flushmmucache_cr3(); set_use32(1); @@ -1848,23 +1809,20 @@ sysret(uint32_t fetchdat) return 1; } - void cpu_register_fast_off_handler(void *timer) { cpu_fast_off_timer = (pc_timer_t *) timer; } - void cpu_fast_off_advance(void) { timer_disable(cpu_fast_off_timer); if (cpu_fast_off_period != 0.0) - timer_on_auto(cpu_fast_off_timer, cpu_fast_off_period); + timer_on_auto(cpu_fast_off_timer, cpu_fast_off_period); } - void cpu_fast_off_period_set(uint16_t val, double period) { @@ -1872,7 +1830,6 @@ cpu_fast_off_period_set(uint16_t val, double period) cpu_fast_off_advance(); } - void cpu_fast_off_reset(void) { @@ -1881,31 +1838,29 @@ cpu_fast_off_reset(void) cpu_fast_off_advance(); } - void smi_raise(void) { if (is486 && (cpu_fast_off_flags & 0x80000000)) - cpu_fast_off_advance(); + cpu_fast_off_advance(); smi_line = 1; } - void nmi_raise(void) { if (is486 && (cpu_fast_off_flags & 0x20000000)) - cpu_fast_off_advance(); + cpu_fast_off_advance(); nmi = 1; } - #ifndef USE_DYNAREC /* This is for compatibility with new x87 code. */ -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); */ + /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); */ } #endif diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 28aab7450..6310ae642 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -1,327 +1,420 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Common 386 CPU code. + * Common 386 CPU code. * * * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #ifndef _386_COMMON_H_ #define _386_COMMON_H_ #include -#define readmemb_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl_no_mmut((s)+(a),b): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl_no_mmut((s)+(a),b):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll_no_mmut((s)+(a),b):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_t)((s)+(a)))) +#define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +#define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +#define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -#define writememb_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl_no_mmut((s)+(a),b,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl_no_mmut((s)+(a),b,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll_no_mmut((s)+(a),b,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememb_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl_no_mmut((s) + (a), b, v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememw_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl_no_mmut((s) + (a), b, v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememl_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll_no_mmut((s) + (a), b, v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememb(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl((s) + (a), v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememw(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl((s) + (a), v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememl(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll((s) + (a), v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememq(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \ + writememql((s) + (a), v); \ + else \ + *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) -#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) -#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) -#define do_mmut_rb2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) -#define do_mmut_rw2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) -#define do_mmut_rl2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) - -#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1) -#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1) -#define do_mmut_wl(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 1) +#define do_mmut_rb(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +#define do_mmut_rw(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +#define do_mmut_rl(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) +#define do_mmut_rb2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +#define do_mmut_rw2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +#define do_mmut_rl2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) +#define do_mmut_wb(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 1) +#define do_mmut_ww(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 1) +#define do_mmut_wl(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 1) int checkio(uint32_t port); +#define check_io_perm(port) \ + if (msw & 1 && ((CPL > IOPL) || (cpu_state.eflags & VM_FLAG))) { \ + int tempi = checkio(port); \ + if (cpu_state.abrt) \ + return 1; \ + if (tempi) { \ + if (cpu_state.eflags & VM_FLAG) \ + x86gpf_expected(NULL, 0); \ + else \ + x86gpf(NULL, 0); \ + return 1; \ + } \ + } -#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \ - { \ - int tempi = checkio(port); \ - if (cpu_state.abrt) return 1; \ - if (tempi) \ - { \ - if (cpu_state.eflags & VM_FLAG) \ - x86gpf_expected(NULL,0); \ - else \ - x86gpf(NULL,0); \ - return 1; \ - } \ - } +#define SEG_CHECK_READ(seg) \ + do { \ + if ((seg)->base == 0xffffffff) { \ + x86gpf("Segment can't read", 0); \ + return 1; \ + } \ + } while (0) -#define SEG_CHECK_READ(seg) \ - do \ - { \ - if ((seg)->base == 0xffffffff) \ - { \ - x86gpf("Segment can't read", 0);\ - return 1; \ - } \ - } while (0) +#define SEG_CHECK_WRITE(seg) \ + do { \ + if ((seg)->base == 0xffffffff) { \ + x86gpf("Segment can't write", 0); \ + return 1; \ + } \ + } while (0) -#define SEG_CHECK_WRITE(seg) \ - do \ - { \ - if ((seg)->base == 0xffffffff) \ - { \ - x86gpf("Segment can't write", 0);\ - return 1; \ - } \ - } while (0) +#define CHECK_READ(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) { \ + x86gpf("Limit check (READ)", 0); \ + return 1; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ + return 1; \ + } -#define CHECK_READ(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \ - { \ - x86gpf("Limit check (READ)", 0); \ - return 1; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ - return 1; \ - } +#define CHECK_READ_REP(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \ + x86gpf("Limit check (READ)", 0); \ + break; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ + break; \ + } -#define CHECK_READ_REP(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ - { \ - x86gpf("Limit check (READ)", 0); \ - break; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ - break; \ - } +#define CHECK_WRITE_COMMON(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) { \ + x86gpf("Limit check (WRITE)", 0); \ + return 1; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ + return 1; \ + } -#define CHECK_WRITE_COMMON(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) \ - { \ - x86gpf("Limit check (WRITE)", 0); \ - return 1; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ - return 1; \ - } +#define CHECK_WRITE(chseg, low, high) \ + CHECK_WRITE_COMMON(chseg, low, high) -#define CHECK_WRITE(chseg, low, high) \ - CHECK_WRITE_COMMON(chseg, low, high) +#define CHECK_WRITE_REP(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \ + x86gpf("Limit check (WRITE REP)", 0); \ + break; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \ + break; \ + } -#define CHECK_WRITE_REP(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ - { \ - x86gpf("Limit check (WRITE REP)", 0); \ - break; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \ - break; \ - } +#define NOTRM \ + if (!(msw & 1) || (cpu_state.eflags & VM_FLAG)) { \ + x86_int(6); \ + return 1; \ + } - -#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\ - { \ - x86_int(6); \ - return 1; \ - } - - - - -static __inline uint8_t fastreadb(uint32_t a) +static __inline uint8_t +fastreadb(uint32_t a) { - uint8_t *t; + uint8_t *t; - if ((a >> 12) == pccache) - return *((uint8_t *)&pccache2[a]); - t = getpccache(a); - if (cpu_state.abrt) - return 0; - pccache = a >> 12; - pccache2 = t; - return *((uint8_t *)&pccache2[a]); + if ((a >> 12) == pccache) + return *((uint8_t *) &pccache2[a]); + t = getpccache(a); + if (cpu_state.abrt) + return 0; + pccache = a >> 12; + pccache2 = t; + return *((uint8_t *) &pccache2[a]); } -static __inline uint16_t fastreadw(uint32_t a) +static __inline uint16_t +fastreadw(uint32_t a) { - uint8_t *t; - uint16_t val; - if ((a&0xFFF)>0xFFE) - { - val = fastreadb(a); - val |= (fastreadb(a + 1) << 8); - return val; - } - if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); - t = getpccache(a); - if (cpu_state.abrt) - return 0; - - pccache = a >> 12; - pccache2 = t; - return *((uint16_t *)&pccache2[a]); -} - -static __inline uint32_t fastreadl(uint32_t a) -{ - uint8_t *t; - uint32_t val; - if ((a&0xFFF)<0xFFD) - { - if ((a>>12)!=pccache) - { - t = getpccache(a); - if (cpu_state.abrt) - return 0; - pccache2 = t; - pccache=a>>12; - } - return *((uint32_t *)&pccache2[a]); - } - val = fastreadw(a); - val |= (fastreadw(a + 2) << 16); + uint8_t *t; + uint16_t val; + if ((a & 0xFFF) > 0xFFE) { + val = fastreadb(a); + val |= (fastreadb(a + 1) << 8); return val; + } + if ((a >> 12) == pccache) + return *((uint16_t *) &pccache2[a]); + t = getpccache(a); + if (cpu_state.abrt) + return 0; + + pccache = a >> 12; + pccache2 = t; + return *((uint16_t *) &pccache2[a]); } -static __inline void *get_ram_ptr(uint32_t a) +static __inline uint32_t +fastreadl(uint32_t a) { - if ((a >> 12) == pccache) - return &pccache2[a]; - else - { - uint8_t *t = getpccache(a); - return &t[a]; + uint8_t *t; + uint32_t val; + if ((a & 0xFFF) < 0xFFD) { + if ((a >> 12) != pccache) { + t = getpccache(a); + if (cpu_state.abrt) + return 0; + pccache2 = t; + pccache = a >> 12; } + return *((uint32_t *) &pccache2[a]); + } + val = fastreadw(a); + val |= (fastreadw(a + 2) << 16); + return val; } -static __inline uint8_t getbyte() +static __inline void * +get_ram_ptr(uint32_t a) { - cpu_state.pc++; - return fastreadb(cs + (cpu_state.pc - 1)); + if ((a >> 12) == pccache) + return &pccache2[a]; + else { + uint8_t *t = getpccache(a); + return &t[a]; + } } -static __inline uint16_t getword() +static __inline uint8_t +getbyte(void) { - cpu_state.pc+=2; - return fastreadw(cs+(cpu_state.pc-2)); + cpu_state.pc++; + return fastreadb(cs + (cpu_state.pc - 1)); } -static __inline uint32_t getlong() +static __inline uint16_t +getword(void) { - cpu_state.pc+=4; - return fastreadl(cs+(cpu_state.pc-4)); + cpu_state.pc += 2; + return fastreadw(cs + (cpu_state.pc - 2)); } -static __inline uint64_t getquad() +static __inline uint32_t +getlong(void) { - cpu_state.pc+=8; - return fastreadl(cs+(cpu_state.pc-8)) | ((uint64_t)fastreadl(cs+(cpu_state.pc-4)) << 32); + cpu_state.pc += 4; + return fastreadl(cs + (cpu_state.pc - 4)); } - - -static __inline uint8_t geteab() +static __inline uint64_t +getquad(void) { - if (cpu_mod == 3) - return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm&3].b.l; - if (eal_r) - return *(uint8_t *)eal_r; - return readmemb(easeg, cpu_state.eaaddr); + cpu_state.pc += 8; + return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32); } -static __inline uint16_t geteaw() +static __inline uint8_t +geteab(void) { - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].w; - if (eal_r) - return *(uint16_t *)eal_r; - return readmemw(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l; + if (eal_r) + return *(uint8_t *) eal_r; + return readmemb(easeg, cpu_state.eaaddr); } -static __inline uint32_t geteal() +static __inline uint16_t +geteaw(void) { - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].l; - if (eal_r) - return *eal_r; - return readmeml(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].w; + if (eal_r) + return *(uint16_t *) eal_r; + return readmemw(easeg, cpu_state.eaaddr); } -static __inline uint64_t geteaq() +static __inline uint32_t +geteal(void) { - return readmemq(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].l; + if (eal_r) + return *eal_r; + return readmeml(easeg, cpu_state.eaaddr); } -static __inline uint8_t geteab_mem() +static __inline uint64_t +geteaq(void) { - if (eal_r) return *(uint8_t *)eal_r; - return readmemb(easeg,cpu_state.eaaddr); + return readmemq(easeg, cpu_state.eaaddr); } -static __inline uint16_t geteaw_mem() + +static __inline uint8_t +geteab_mem(void) { - if (eal_r) return *(uint16_t *)eal_r; - return readmemw(easeg,cpu_state.eaaddr); + if (eal_r) + return *(uint8_t *) eal_r; + return readmemb(easeg, cpu_state.eaaddr); } -static __inline uint32_t geteal_mem() +static __inline uint16_t +geteaw_mem(void) { - if (eal_r) return *eal_r; - return readmeml(easeg,cpu_state.eaaddr); + if (eal_r) + return *(uint16_t *) eal_r; + return readmemw(easeg, cpu_state.eaaddr); } - -static __inline int seteaq_cwc(void) +static __inline uint32_t +geteal_mem(void) { - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - return 0; + if (eal_r) + return *eal_r; + return readmeml(easeg, cpu_state.eaaddr); } -static __inline void seteaq(uint64_t v) +static __inline int +seteaq_cwc(void) { - if (seteaq_cwc()) - return; - writememql(easeg + cpu_state.eaaddr, v); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + return 0; } -#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v -#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v -#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v +static __inline void +seteaq(uint64_t v) +{ + if (seteaq_cwc()) + return; + writememql(easeg + cpu_state.eaaddr, v); +} -#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); -#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); -#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); +#define seteab(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); \ + } else if (cpu_rm & 4) \ + cpu_state.regs[cpu_rm & 3].b.h = v; \ + else \ + cpu_state.regs[cpu_rm].b.l = v +#define seteaw(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].w = v +#define seteal(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].l = v -#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ -#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 -#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ -#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 +#define seteab_mem(v) \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); +#define seteaw_mem(v) \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); +#define seteal_mem(v) \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); + +#define getbytef() \ + ((uint8_t) (fetchdat)); \ + cpu_state.pc++ +#define getwordf() \ + ((uint16_t) (fetchdat)); \ + cpu_state.pc += 2 +#define getbyte2f() \ + ((uint8_t) (fetchdat >> 8)); \ + cpu_state.pc++ +#define getword2f() \ + ((uint16_t) (fetchdat >> 8)); \ + cpu_state.pc += 2 #endif diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index ca7b94647..f2e04b54a 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -4,12 +4,12 @@ #include #include #if defined(__APPLE__) && defined(__aarch64__) -#include +# include #endif #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H @@ -28,164 +28,161 @@ #include <86box/machine.h> #include <86box/gdbstub.h> #ifdef USE_DYNAREC -#include "codegen.h" -#ifdef USE_NEW_DYNAREC -#include "codegen_backend.h" -#endif +# include "codegen.h" +# ifdef USE_NEW_DYNAREC +# include "codegen_backend.h" +# endif #endif #ifdef IS_DYNAREC -#undef IS_DYNAREC +# undef IS_DYNAREC #endif #include "386_common.h" #if defined(__APPLE__) && defined(__aarch64__) -#include +# include #endif #define CPU_BLOCK_END() cpu_block_end = 1 - int inrecomp = 0, cpu_block_end = 0; int cpu_end_block_after_ins = 0; - #ifdef ENABLE_386_DYNAREC_LOG int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; - void x386_dynarec_log(const char *fmt, ...) { va_list ap; if (x386_dynarec_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x386_dynarec_log(fmt, ...) +# define x386_dynarec_log(fmt, ...) #endif - -static __inline void fetch_ea_32_long(uint32_t rmdat) +static __inline void +fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (cpu_rm == 4) - { - uint8_t sib = rmdat >> 8; + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) { + uint8_t sib = rmdat >> 8; - switch (cpu_mod) - { - case 0: - cpu_state.eaaddr = cpu_state.regs[sib & 7].l; - cpu_state.pc++; - break; - case 1: - cpu_state.pc++; - cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; - break; - case 2: - cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; - cpu_state.pc += 5; - break; - } - /*SIB byte present*/ - if ((sib & 7) == 5 && !cpu_mod) - cpu_state.eaaddr = getlong(); - else if ((sib & 6) == 4 && !cpu_state.ssegs) - { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (((sib >> 3) & 7) != 4) - cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); - } - else - { - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) - { - if (cpu_rm == 5 && !cpu_state.ssegs) - { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (cpu_mod == 1) - { - cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); - cpu_state.pc++; - } - else - { - cpu_state.eaaddr += getlong(); - } - } - else if (cpu_rm == 5) - { - cpu_state.eaaddr = getlong(); - } - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t) (int8_t) getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } else { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) { + if (cpu_rm == 5 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) { + cpu_state.eaaddr += ((uint32_t) (int8_t) (rmdat >> 8)); + cpu_state.pc++; + } else { + cpu_state.eaaddr += getlong(); + } + } else if (cpu_rm == 5) { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -static __inline void fetch_ea_16_long(uint32_t rmdat) +static __inline void +fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (!cpu_mod && cpu_rm == 6) - { - cpu_state.eaaddr = getword(); - } - else - { - switch (cpu_mod) - { - case 0: - cpu_state.eaaddr = 0; - break; - case 1: - cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; - break; - case 2: - cpu_state.eaaddr = getword(); - break; - } - cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); - if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) - { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - cpu_state.eaaddr &= 0xFFFF; - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) { + cpu_state.eaaddr = getword(); + } else { + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t) (int8_t) (rmdat >> 8); + cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } -#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_16_long(rmdat); \ + if (cpu_state.abrt) \ + return 1; \ + } +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_32_long(rmdat); \ + } \ + if (cpu_state.abrt) \ + return 1 #include "x86_flags.h" - /*Prefetch emulation is a fairly simplistic model: - All instruction bytes must be fetched before it starts. - Cycles used for non-instruction memory accesses are counted and subtracted @@ -195,150 +192,145 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) Note that this is only used for 286 / 386 systems. It is disabled when the internal cache on 486+ CPUs is enabled. */ -static int prefetch_bytes = 0; +static int prefetch_bytes = 0; static int prefetch_prefixes = 0; -static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +static void +prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) { - int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + int mem_cycles = reads * cpu_cycles_read + reads_l * cpu_cycles_read_l + writes * cpu_cycles_write + writes_l * cpu_cycles_write_l; - if (instr_cycles < mem_cycles) - instr_cycles = mem_cycles; + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; - prefetch_bytes -= prefetch_prefixes; - prefetch_bytes -= bytes; - if (modrm != -1) - { - if (ea32) - { - if ((modrm & 7) == 4) - { - if ((modrm & 0x700) == 0x500) - prefetch_bytes -= 5; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 5; - } - else - { - if ((modrm & 0xc7) == 0x05) - prefetch_bytes -= 4; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes--; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 4; - } - } - else - { - if ((modrm & 0xc7) == 0x06) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) != 0xc0) - prefetch_bytes -= ((modrm & 0xc0) >> 6); - } - } + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) { + if (ea32) { + if ((modrm & 7) == 4) { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } else { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } else { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } - /* Fill up prefetch queue */ - while (prefetch_bytes < 0) - { - prefetch_bytes += cpu_prefetch_width; - cycles -= cpu_prefetch_cycles; - } + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } - /* Subtract cycles used for memory access by instruction */ - instr_cycles -= mem_cycles; + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; - while (instr_cycles >= cpu_prefetch_cycles) - { - prefetch_bytes += cpu_prefetch_width; - instr_cycles -= cpu_prefetch_cycles; - } + while (instr_cycles >= cpu_prefetch_cycles) { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } - prefetch_prefixes = 0; - if (prefetch_bytes > 16) - prefetch_bytes = 16; + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; } -static void prefetch_flush() +static void +prefetch_flush(void) { - prefetch_bytes = 0; + prefetch_bytes = 0; } -#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ - do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); \ + } while (0) -#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_PREFIX() \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_prefixes++; \ + } while (0) #define PREFETCH_FLUSH() prefetch_flush() - -#define OP_TABLE(name) ops_ ## name +#define OP_TABLE(name) ops_##name #if 0 -#define CLOCK_CYCLES(c) \ - {\ - if (fpu_cycles > 0) {\ - fpu_cycles -= (c);\ - if (fpu_cycles < 0) {\ - cycles += fpu_cycles;\ - }\ - } else {\ - cycles -= (c);\ - }\ - } -#define CLOCK_CYCLES_FPU(c) cycles -= (c) -#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) +# define CLOCK_CYCLES(c) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (c); \ + if (fpu_cycles < 0) { \ + cycles += fpu_cycles; \ + } \ + } else { \ + cycles -= (c); \ + } \ + } +# define CLOCK_CYCLES_FPU(c) cycles -= (c) +# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #else -#define CLOCK_CYCLES(c) cycles -= (c) -#define CLOCK_CYCLES_FPU(c) cycles -= (c) -#define CONCURRENCY_CYCLES(c) +# define CLOCK_CYCLES(c) cycles -= (c) +# define CLOCK_CYCLES_FPU(c) cycles -= (c) +# define CONCURRENCY_CYCLES(c) #endif #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) - #include "386_ops.h" - #define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #ifdef USE_DYNAREC -int cycles_main = 0; -static int cycles_old = 0; -static uint64_t tsc_old = 0; +int cycles_main = 0; +static int cycles_old = 0; +static uint64_t tsc_old = 0; -#ifdef USE_ACYCS +# ifdef USE_ACYCS int acycs = 0; -#endif - +# endif void update_tsc(void) { - int cycdiff; + int cycdiff; uint64_t delta; cycdiff = cycles_old - cycles; -#ifdef USE_ACYCS +# ifdef USE_ACYCS if (inrecomp) - cycdiff += acycs; -#endif + cycdiff += acycs; +# endif delta = tsc - tsc_old; if (delta > 0) { - /* TSC has changed, this means interim timer processing has happened, - see how much we still need to add. */ - cycdiff -= delta; + /* TSC has changed, this means interim timer processing has happened, + see how much we still need to add. */ + cycdiff -= delta; } if (cycdiff > 0) - tsc += cycdiff; + tsc += cycdiff; if (cycdiff > 0) { - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process_inline(); + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process_inline(); } } - static __inline void exec386_dynarec_int(void) { @@ -346,530 +338,523 @@ exec386_dynarec_int(void) x86_was_reset = 0; while (!cpu_block_end) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - oldcpl = CPL; -#endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; +# ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +# endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); -#ifdef ENABLE_386_DYNAREC_LOG - if (in_smm) - x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); -#endif + fetchdat = fastreadl(cs + cpu_state.pc); +# ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +# endif - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + trap = cpu_state.flags & T_FLAG; - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - } + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } -#ifndef USE_NEW_DYNAREC - if (!use32) - cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif - if (((cs + cpu_state.pc) >> 12) != pccache) - CPU_BLOCK_END(); + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) - CPU_BLOCK_END(); - if (smi_line) - CPU_BLOCK_END(); - else if (trap) - CPU_BLOCK_END(); - else if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) - CPU_BLOCK_END(); + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (smi_line) + CPU_BLOCK_END(); + else if (trap) + CPU_BLOCK_END(); + else if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) + CPU_BLOCK_END(); } if (!cpu_state.abrt && trap) { - trap = 0; -#ifndef USE_NEW_DYNAREC - oldcs = CS; -#endif - cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; - x86_int(1); + trap = 0; +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + dr[6] |= 0x4000; + x86_int(1); } cpu_end_block_after_ins = 0; } - static __inline void exec386_dynarec_dyn(void) { uint32_t start_pc = 0, phys_addr = get_phys(cs + cpu_state.pc); - int hash = HASH(phys_addr); -#ifdef USE_NEW_DYNAREC + int hash = HASH(phys_addr); +# ifdef USE_NEW_DYNAREC codeblock_t *block = &codeblock[codeblock_hash[hash]]; -#else +# else codeblock_t *block = codeblock_hash[hash]; -#endif +# endif int valid_block = 0; -#ifdef USE_NEW_DYNAREC +# ifdef USE_NEW_DYNAREC if (!cpu_state.abrt) -#else +# else if (block && !cpu_state.abrt) -#endif +# endif { - page_t *page = &pages[phys_addr >> 12]; + page_t *page = &pages[phys_addr >> 12]; - /* Block must match current CS, PC, code segment size, - and physical address. The physical address check will - also catch any page faults at this stage */ - valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && - (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (!valid_block) { - uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); -#ifdef USE_NEW_DYNAREC - int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + /* Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage */ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) { + uint64_t mask = (uint64_t) 1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); +# ifdef USE_NEW_DYNAREC + int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); - if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) -#else - if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) -#endif - { - /* Walk page tree to see if we find the correct block */ - codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); - if (new_block) { - valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && - (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (valid_block) { - block = new_block; -#ifdef USE_NEW_DYNAREC - codeblock_hash[hash] = get_block_nr(block); -#endif - } - } - } - } + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) +# else + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) +# endif + { + /* Walk page tree to see if we find the correct block */ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) { + block = new_block; +# ifdef USE_NEW_DYNAREC + codeblock_hash[hash] = get_block_nr(block); +# endif + } + } + } + } - if (valid_block && (block->page_mask & *block->dirty_mask)) { -#ifdef USE_NEW_DYNAREC - codegen_check_flush(page, page->dirty_mask, phys_addr); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; -#else - codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); - page->dirty_mask[(phys_addr >> 10) & 3] = 0; - if (!block->valid) - valid_block = 0; -#endif - } - if (valid_block && block->page_mask2) { - /* We don't want the second page to cause a page - fault at this stage - that would break any - code crossing a page boundary where the first - page is present but the second isn't. Instead - allow the first page to be interpreted and for - the page fault to occur when the page boundary - is actually crossed.*/ -#ifdef USE_NEW_DYNAREC - uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); -#else - uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); -#endif - page_t *page_2 = &pages[phys_addr_2 >> 12]; + if (valid_block && (block->page_mask & *block->dirty_mask)) { +# ifdef USE_NEW_DYNAREC + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +# else + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +# endif + } + if (valid_block && block->page_mask2) { + /* We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ +# ifdef USE_NEW_DYNAREC + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); +# else + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); +# endif + page_t *page_2 = &pages[phys_addr_2 >> 12]; - if ((block->phys_2 ^ phys_addr_2) & ~0xfff) - valid_block = 0; - else if (block->page_mask2 & *block->dirty_mask2) { -#ifdef USE_NEW_DYNAREC - codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; -#else - codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); - page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; - if (!block->valid) - valid_block = 0; -#endif - } - } -#ifdef USE_NEW_DYNAREC - if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) { - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - if (block->flags & CODEBLOCK_BYTE_MASK) - block->flags |= CODEBLOCK_NO_IMMEDIATES; - else - block->flags |= CODEBLOCK_BYTE_MASK; - } - if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) -#else - if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) -#endif - { - /* FPU top-of-stack does not match the value this block was compiled - with, re-compile using dynamic top-of-stack*/ -#ifdef USE_NEW_DYNAREC - block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); -#else - block->flags &= ~CODEBLOCK_STATIC_TOP; - block->was_recompiled = 0; -#endif - } + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) { +# ifdef USE_NEW_DYNAREC + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +# else + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +# endif + } + } +# ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) +# else + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) +# endif + { + /* FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ +# ifdef USE_NEW_DYNAREC + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); +# else + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; +# endif + } } -#ifdef USE_NEW_DYNAREC +# ifdef USE_NEW_DYNAREC if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) -#else +# else if (valid_block && block->was_recompiled) -#endif +# endif { - void (*code)() = (void *)&block->data[BLOCK_START]; + void (*code)(void) = (void *) &block->data[BLOCK_START]; -#ifndef USE_NEW_DYNAREC - codeblock_hash[hash] = block; -#endif - inrecomp = 1; - code(); -#ifdef USE_ACYCS - acycs = 0; -#endif - inrecomp = 0; +# ifndef USE_NEW_DYNAREC + codeblock_hash[hash] = block; +# endif + inrecomp = 1; + code(); +# ifdef USE_ACYCS + acycs = 0; +# endif + inrecomp = 0; -#ifndef USE_NEW_DYNAREC - if (!use32) cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif } else if (valid_block && !cpu_state.abrt) { -#ifdef USE_NEW_DYNAREC - start_pc = cs + cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; -#else - start_pc = cpu_state.pc; -#endif +# ifdef USE_NEW_DYNAREC + start_pc = cs + cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +# else + start_pc = cpu_state.pc; +# endif - cpu_block_end = 0; - x86_was_reset = 0; + cpu_block_end = 0; + x86_was_reset = 0; -#if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(0); -#endif - codegen_block_start_recompile(block); - codegen_in_recompile = 1; +# if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(0); +# endif + codegen_block_start_recompile(block); + codegen_in_recompile = 1; - while (!cpu_block_end) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - oldcpl = CPL; -#endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + while (!cpu_block_end) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +# endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); -#ifdef ENABLE_386_DYNAREC_LOG - if (in_smm) - x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); -#endif + fetchdat = fastreadl(cs + cpu_state.pc); +# ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +# endif - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; - cpu_state.pc++; + cpu_state.pc++; - codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc - 1); - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + if (x86_was_reset) + break; + } -#ifndef USE_NEW_DYNAREC - if (!use32) - cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif - /* Cap source code at 4000 bytes per block; this - will prevent any block from spanning more than - 2 pages. In practice this limit will never be - hit, as host block size is only 2kB*/ -#ifdef USE_NEW_DYNAREC - if (((cs + cpu_state.pc) - start_pc) >= max_block_size) -#else - if ((cpu_state.pc - start_pc) > 1000) -#endif - CPU_BLOCK_END(); + /* Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +# ifdef USE_NEW_DYNAREC + if (((cs + cpu_state.pc) - start_pc) >= max_block_size) +# else + if ((cpu_state.pc - start_pc) > 1000) +# endif + CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - if (smi_line) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) - CPU_BLOCK_END(); + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + if (smi_line) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) { - if (!(cpu_state.abrt & ABRT_EXPECTED)) - codegen_block_remove(); - CPU_BLOCK_END(); - } - } + if (cpu_state.abrt) { + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); + CPU_BLOCK_END(); + } + } - cpu_end_block_after_ins = 0; + cpu_end_block_after_ins = 0; - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) - codegen_block_end_recompile(block); + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + codegen_block_end_recompile(block); - if (x86_was_reset) - codegen_reset(); + if (x86_was_reset) + codegen_reset(); - codegen_in_recompile = 0; -#if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(1); -#endif + codegen_in_recompile = 0; +# if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(1); +# endif } else if (!cpu_state.abrt) { - /* Mark block but do not recompile */ -#ifdef USE_NEW_DYNAREC - start_pc = cs + cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; -#else - start_pc = cpu_state.pc; -#endif + /* Mark block but do not recompile */ +# ifdef USE_NEW_DYNAREC + start_pc = cs + cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +# else + start_pc = cpu_state.pc; +# endif - cpu_block_end = 0; - x86_was_reset = 0; + cpu_block_end = 0; + x86_was_reset = 0; - codegen_block_init(phys_addr); + codegen_block_init(phys_addr); - while (!cpu_block_end) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - oldcpl = CPL; -#endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + while (!cpu_block_end) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +# endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - codegen_endpc = (cs + cpu_state.pc) + 8; - fetchdat = fastreadl(cs + cpu_state.pc); + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); -#ifdef ENABLE_386_DYNAREC_LOG - if (in_smm) - x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); -#endif +# ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +# endif - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; - cpu_state.pc++; + cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + if (x86_was_reset) + break; + } -#ifndef USE_NEW_DYNAREC - if (!use32) - cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif - /* Cap source code at 4000 bytes per block; this - will prevent any block from spanning more than - 2 pages. In practice this limit will never be - hit, as host block size is only 2kB */ -#ifdef USE_NEW_DYNAREC - if (((cs + cpu_state.pc) - start_pc) >= max_block_size) -#else - if ((cpu_state.pc - start_pc) > 1000) -#endif - CPU_BLOCK_END(); + /* Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB */ +# ifdef USE_NEW_DYNAREC + if (((cs + cpu_state.pc) - start_pc) >= max_block_size) +# else + if ((cpu_state.pc - start_pc) > 1000) +# endif + CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - if (smi_line) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) - CPU_BLOCK_END(); + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + if (smi_line) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) { - if (!(cpu_state.abrt & ABRT_EXPECTED)) - codegen_block_remove(); - CPU_BLOCK_END(); - } - } + if (cpu_state.abrt) { + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); + CPU_BLOCK_END(); + } + } - cpu_end_block_after_ins = 0; + cpu_end_block_after_ins = 0; - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) - codegen_block_end(); + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + codegen_block_end(); - if (x86_was_reset) - codegen_reset(); + if (x86_was_reset) + codegen_reset(); } -#ifdef USE_NEW_DYNAREC +# ifdef USE_NEW_DYNAREC else - cpu_state.oldpc = cpu_state.pc; -#endif + cpu_state.oldpc = cpu_state.pc; +# endif } - void exec386_dynarec(int cycs) { - int vector, tempi; - int cycdiff; - int oldcyc, oldcyc2; + int vector, tempi; + int cycdiff; + int oldcyc, oldcyc2; uint64_t oldtsc, delta; int cyc_period = cycs / 2000; /*5us*/ -#ifdef USE_ACYCS +# ifdef USE_ACYCS acycs = 0; -#endif +# endif cycles_main += cycs; while (cycles_main > 0) { - int cycles_start; + int cycles_start; - cycles += cyc_period; - cycles_start = cycles; + cycles += cyc_period; + cycles_start = cycles; - while (cycles > 0) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - cpu_state.oldpc = cpu_state.pc; - oldcpl = CPL; - cpu_state.op32 = use32; + while (cycles > 0) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; - cycdiff = 0; -#endif - oldcyc = oldcyc2 = cycles; - cycles_old = cycles; - oldtsc = tsc; - tsc_old = tsc; - if (!CACHE_ON()) /*Interpret block*/ - { - exec386_dynarec_int(); - } - else - { - exec386_dynarec_dyn(); - } + cycdiff = 0; +# endif + oldcyc = oldcyc2 = cycles; + cycles_old = cycles; + oldtsc = tsc; + tsc_old = tsc; + if (!CACHE_ON()) /*Interpret block*/ + { + exec386_dynarec_int(); + } else { + exec386_dynarec_dyn(); + } - if (cpu_state.abrt) { - flags_rebuild(); - tempi = cpu_state.abrt & ABRT_MASK; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - cpu_state.pc = cpu_state.oldpc; -#ifndef USE_NEW_DYNAREC - CS = oldcs; -#endif - pmodeint(8, 0); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); -#ifdef ENABLE_386_DYNAREC_LOG - x386_dynarec_log("Triple fault - reset\n"); -#endif - } - } - } + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt & ABRT_MASK; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; +# ifndef USE_NEW_DYNAREC + CS = oldcs; +# endif + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +# ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +# endif + } + } + } - if (smi_line) - enter_smm_check(0); - else if (nmi && nmi_enable && nmi_mask) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; -#endif - cpu_state.oldpc = cpu_state.pc; - x86_int(2); - nmi_enable = 0; -#ifdef OLD_NMI_BEHAVIOR - if (nmi_auto_clear) { - nmi_auto_clear = 0; - nmi = 0; - } -#else - nmi = 0; -#endif - } else if ((cpu_state.flags & I_FLAG) && pic.int_pending) { - vector = picinterrupt(); - if (vector != -1) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; -#endif - cpu_state.oldpc = cpu_state.pc; - x86_int(vector); - } - } + if (smi_line) + enter_smm_check(0); + else if (nmi && nmi_enable && nmi_mask) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; +# ifdef OLD_NMI_BEHAVIOR + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } +# else + nmi = 0; +# endif + } else if ((cpu_state.flags & I_FLAG) && pic.int_pending) { + vector = picinterrupt(); + if (vector != -1) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + x86_int(vector); + } + } - cycdiff = oldcyc - cycles; - delta = tsc - oldtsc; - if (delta > 0) { - /* TSC has changed, this means interim timer processing has happened, - see how much we still need to add. */ - cycdiff -= delta; - if (cycdiff > 0) - tsc += cycdiff; - } else { - /* TSC has not changed. */ - tsc += cycdiff; - } + cycdiff = oldcyc - cycles; + delta = tsc - oldtsc; + if (delta > 0) { + /* TSC has changed, this means interim timer processing has happened, + see how much we still need to add. */ + cycdiff -= delta; + if (cycdiff > 0) + tsc += cycdiff; + } else { + /* TSC has not changed. */ + tsc += cycdiff; + } - if (cycdiff > 0) { - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); - } + if (cycdiff > 0) { + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process_inline(); + } -#ifdef USE_GDBSTUB - if (gdbstub_instruction()) - return; -#endif - } +# ifdef USE_GDBSTUB + if (gdbstub_instruction()) + return; +# endif + } - cycles_main -= (cycles_start - cycles); + cycles_main -= (cycles_start - cycles); } } #endif diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index 0b02676f8..f3e2f6e6e 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -5,7 +5,7 @@ #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #include <86box/86box.h> @@ -25,57 +25,61 @@ #define CPU_BLOCK_END() cpu_block_end = 1 #ifndef IS_DYNAREC -#define IS_DYNAREC +# define IS_DYNAREC #endif #include "386_common.h" - -static __inline void fetch_ea_32_long(uint32_t rmdat) +static __inline void +fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -static __inline void fetch_ea_16_long(uint32_t rmdat) +static __inline void +fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); -#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); - +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + if (cpu_mod != 3) \ + fetch_ea_16_long(rmdat); +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + if (cpu_mod != 3) \ + fetch_ea_32_long(rmdat); #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32) #define PREFETCH_PREFIX() #define PREFETCH_FLUSH() -#define OP_TABLE(name) dynarec_ops_ ## name +#define OP_TABLE(name) dynarec_ops_##name #define CLOCK_CYCLES(c) #if 0 -#define CLOCK_CYCLES_FPU(c) -#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) +# define CLOCK_CYCLES_FPU(c) +# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #else -#define CLOCK_CYCLES_FPU(c) -#define CONCURRENCY_CYCLES(c) +# define CLOCK_CYCLES_FPU(c) +# define CONCURRENCY_CYCLES(c) #endif #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 73b7cdc7d..ec46ba0ae 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -1,24 +1,24 @@ /* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the VARCem Project. + * This file is part of the VARCem Project. * - * 286/386+ instruction handlers list. + * 286/386+ instruction handlers list. * * * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * leilei, - * Miran Grca, + * Authors: Fred N. van Kempen, + * Sarah Walker, + * leilei, + * Miran Grca, * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 leilei. - * Copyright 2016-2018 Miran Grca. + * Copyright 2018 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 leilei. + * Copyright 2016-2018 Miran Grca. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,128 +40,137 @@ */ #include "x86_ops.h" +#define ILLEGAL_ON(cond) \ + do { \ + if ((cond)) { \ + cpu_state.pc = cpu_state.oldpc; \ + x86illegal(); \ + return 0; \ + } \ + } while (0) -#define ILLEGAL_ON(cond) \ - do \ - { \ - if ((cond)) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 0; \ - } \ - } while (0) - -static __inline void PUSH_W(uint16_t val) +static __inline void +PUSH_W(uint16_t val) { - if (stack32) - { - writememw(ss, ESP - 2, val); if (cpu_state.abrt) return; - ESP -= 2; - } - else - { - writememw(ss, (SP - 2) & 0xFFFF, val); if (cpu_state.abrt) return; - SP -= 2; - } + if (stack32) { + writememw(ss, ESP - 2, val); + if (cpu_state.abrt) + return; + ESP -= 2; + } else { + writememw(ss, (SP - 2) & 0xFFFF, val); + if (cpu_state.abrt) + return; + SP -= 2; + } } -static __inline void PUSH_L(uint32_t val) +static __inline void +PUSH_L(uint32_t val) { - if (stack32) - { - writememl(ss, ESP - 4, val); if (cpu_state.abrt) return; - ESP -= 4; - } - else - { - writememl(ss, (SP - 4) & 0xFFFF, val); if (cpu_state.abrt) return; - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, val); + if (cpu_state.abrt) + return; + ESP -= 4; + } else { + writememl(ss, (SP - 4) & 0xFFFF, val); + if (cpu_state.abrt) + return; + SP -= 4; + } } -static __inline uint16_t POP_W() +static __inline uint16_t +POP_W(void) { - uint16_t ret; - if (stack32) - { - ret = readmemw(ss, ESP); if (cpu_state.abrt) return 0; - ESP += 2; - } - else - { - ret = readmemw(ss, SP); if (cpu_state.abrt) return 0; - SP += 2; - } - return ret; + uint16_t ret; + if (stack32) { + ret = readmemw(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; + } else { + ret = readmemw(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 2; + } + return ret; } -static __inline uint32_t POP_L() +static __inline uint32_t +POP_L(void) { - uint32_t ret; - if (stack32) - { - ret = readmeml(ss, ESP); if (cpu_state.abrt) return 0; - ESP += 4; - } - else - { - ret = readmeml(ss, SP); if (cpu_state.abrt) return 0; - SP += 4; - } - return ret; + uint32_t ret; + if (stack32) { + ret = readmeml(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + ret = readmeml(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } + return ret; } -static __inline uint16_t POP_W_seg(uint32_t seg) +static __inline uint16_t +POP_W_seg(uint32_t seg) { - uint16_t ret; - if (stack32) - { - ret = readmemw(seg, ESP); if (cpu_state.abrt) return 0; - ESP += 2; - } - else - { - ret = readmemw(seg, SP); if (cpu_state.abrt) return 0; - SP += 2; - } - return ret; + uint16_t ret; + if (stack32) { + ret = readmemw(seg, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; + } else { + ret = readmemw(seg, SP); + if (cpu_state.abrt) + return 0; + SP += 2; + } + return ret; } -static __inline uint32_t POP_L_seg(uint32_t seg) +static __inline uint32_t +POP_L_seg(uint32_t seg) { - uint32_t ret; - if (stack32) - { - ret = readmeml(seg, ESP); if (cpu_state.abrt) return 0; - ESP += 4; - } - else - { - ret = readmeml(seg, SP); if (cpu_state.abrt) return 0; - SP += 4; - } - return ret; + uint32_t ret; + if (stack32) { + ret = readmeml(seg, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + ret = readmeml(seg, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } + return ret; } static int fopcode; -static int ILLEGAL(uint32_t fetchdat) +static int +ILLEGAL(uint32_t fetchdat) { - pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode); - cpu_state.pc = cpu_state.oldpc; + pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode); + cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; + x86illegal(); + return 0; } - #ifdef ENABLE_386_DYNAREC_LOG -extern void x386_dynarec_log(const char *fmt, ...); +extern void x386_dynarec_log(const char *fmt, ...); #else -#ifndef x386_dynarec_log -#define x386_dynarec_log(fmt, ...) -#endif +# ifndef x386_dynarec_log +# define x386_dynarec_log(fmt, ...) +# endif #endif #include "x86seg.h" @@ -196,9 +205,9 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_pmode.h" #include "x86_ops_prefix.h" #ifdef IS_DYNAREC -#include "x86_ops_rep_dyn.h" +# include "x86_ops_rep_dyn.h" #else -#include "x86_ops_rep.h" +# include "x86_ops_rep.h" #endif #include "x86_ops_ret.h" #include "x86_ops_set.h" @@ -211,161 +220,164 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_3dnow.h" #include - -static int opVPCEXT(uint32_t fetchdat) +static int +opVPCEXT(uint32_t fetchdat) { - uint8_t b1, b2; - uint16_t cent; - time_t now; - struct tm *tm; + uint8_t b1, b2; + uint16_t cent; + time_t now; + struct tm *tm; - if (!is_vpc) /* only emulate this on Virtual PC machines */ - return ILLEGAL(fetchdat); + if (!is_vpc) /* only emulate this on Virtual PC machines */ + return ILLEGAL(fetchdat); - cpu_state.pc += 2; + cpu_state.pc += 2; - b1 = fetchdat & 0xff; - b2 = (fetchdat >> 8) & 0xff; + b1 = fetchdat & 0xff; + b2 = (fetchdat >> 8) & 0xff; - /* a lot of these opcodes (which?) return illegal instruction in user mode */ - ILLEGAL_ON(CPL > 0); + /* a lot of these opcodes (which?) return illegal instruction in user mode */ + ILLEGAL_ON(CPL > 0); - CLOCK_CYCLES(1); + CLOCK_CYCLES(1); - /* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */ - if (b1 == 0x03) { - (void)time(&now); - tm = localtime(&now); - } + /* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */ + if (b1 == 0x03) { + (void) time(&now); + tm = localtime(&now); + } - if ((b1 == 0x07) && (b2 == 0x0b)) { - /* 0f 3f 07 0b: unknown, EDX output depends on EAX input */ - switch (EAX) { - case 0x00000000: - EDX = 0x00000003; - break; + if ((b1 == 0x07) && (b2 == 0x0b)) { + /* 0f 3f 07 0b: unknown, EDX output depends on EAX input */ + switch (EAX) { + case 0x00000000: + EDX = 0x00000003; + break; - case 0x00000001: - EDX = 0x00000012; - break; + case 0x00000001: + EDX = 0x00000012; + break; - case 0x00000002: - case 0x00000003: - case 0x00000004: - case 0x00000005: - EDX = 0x00000001; - break; + case 0x00000002: + case 0x00000003: + case 0x00000004: + case 0x00000005: + EDX = 0x00000001; + break; - case 0x00000007: - EDX = 0x0000009c; - break; + case 0x00000007: + EDX = 0x0000009c; + break; - default: - EDX = 0x00000000; - if (EAX > 0x00000012) /* unknown EAX values set zero flag */ - cpu_state.flags &= ~(Z_FLAG); - } - } else if ((b1 == 0x03) && (b2 == 0x00)) { - /* 0f 3f 03 00: host time in BCD */ - EDX = BCD8(tm->tm_hour); - ECX = BCD8(tm->tm_min); - EAX = BCD8(tm->tm_sec); - } else if ((b1 == 0x03) && (b2 == 0x01)) { - /* 0f 3f 03 00: host date in BCD */ - EDX = BCD8(tm->tm_year % 100); - ECX = BCD8(tm->tm_mon + 1); - EAX = BCD8(tm->tm_mday); - cent = (((tm->tm_year - (tm->tm_year % 100)) / 100) % 4); /* Sunday = 0 */ - EBX = ((tm->tm_mday + tm->tm_mon + (tm->tm_year % 100) + cent + 3) % 7); - } else if ((b1 == 0x03) && (b2 == 0x03)) { - /* 0f 3f 03 03: host time in binary */ - EDX = tm->tm_hour; - ECX = tm->tm_min; - EAX = tm->tm_sec; - } else if ((b1 == 0x03) && (b2 == 0x04)) { - /* 0f 3f 03 04: host date in binary */ - EDX = 1900 + tm->tm_year; - ECX = tm->tm_mon + 1; - EBX = tm->tm_mday; - } else if ((b1 == 0x03) && (b2 == 0x05)) { - /* 0f 3f 03 05: unknown */ - EBX = 0x0000000F; - ECX = 0x0000000A; - } else if ((b1 == 0x03) && (b2 == 0x06)) { - /* 0f 3f 03 06: some kind of timestamp. BX jumps around very quickly, CX not so much. */ - EBX = 0x00000000; - ECX = 0x00000000; - } else if ((b1 == 0x03) && (b2 >= 0x07)) { - /* 0f 3f 03 07+: set zero flag */ - cpu_state.flags &= ~(Z_FLAG); - } else if ((b1 == 0x0a) && (b2 == 0x00)) { - /* 0f 3f 0a 00: memory size in KB */ - EAX = mem_size; - } else if ((b1 == 0x11) && (b2 == 0x00)) { - /* 0f 3f 11 00: unknown, set EAX to 0 */ - EAX = 0x00000000; - } else if ((b1 == 0x11) && (b2 == 0x01)) { - /* 0f 3f 11 00: unknown, set EAX to 0 and set zero flag */ - EAX = 0x00000000; - cpu_state.flags &= ~(Z_FLAG); - } else if ((b1 == 0x11) && (b2 == 0x02)) { - /* 0f 3f 11 02: unknown, no-op */ - } else { - /* other unknown opcodes: illegal instruction */ - cpu_state.pc = cpu_state.oldpc; + default: + EDX = 0x00000000; + if (EAX > 0x00000012) /* unknown EAX values set zero flag */ + cpu_state.flags &= ~(Z_FLAG); + } + } else if ((b1 == 0x03) && (b2 == 0x00)) { + /* 0f 3f 03 00: host time in BCD */ + EDX = BCD8(tm->tm_hour); + ECX = BCD8(tm->tm_min); + EAX = BCD8(tm->tm_sec); + } else if ((b1 == 0x03) && (b2 == 0x01)) { + /* 0f 3f 03 00: host date in BCD */ + EDX = BCD8(tm->tm_year % 100); + ECX = BCD8(tm->tm_mon + 1); + EAX = BCD8(tm->tm_mday); + cent = (((tm->tm_year - (tm->tm_year % 100)) / 100) % 4); /* Sunday = 0 */ + EBX = ((tm->tm_mday + tm->tm_mon + (tm->tm_year % 100) + cent + 3) % 7); + } else if ((b1 == 0x03) && (b2 == 0x03)) { + /* 0f 3f 03 03: host time in binary */ + EDX = tm->tm_hour; + ECX = tm->tm_min; + EAX = tm->tm_sec; + } else if ((b1 == 0x03) && (b2 == 0x04)) { + /* 0f 3f 03 04: host date in binary */ + EDX = 1900 + tm->tm_year; + ECX = tm->tm_mon + 1; + EBX = tm->tm_mday; + } else if ((b1 == 0x03) && (b2 == 0x05)) { + /* 0f 3f 03 05: unknown */ + EBX = 0x0000000F; + ECX = 0x0000000A; + } else if ((b1 == 0x03) && (b2 == 0x06)) { + /* 0f 3f 03 06: some kind of timestamp. BX jumps around very quickly, CX not so much. */ + EBX = 0x00000000; + ECX = 0x00000000; + } else if ((b1 == 0x03) && (b2 >= 0x07)) { + /* 0f 3f 03 07+: set zero flag */ + cpu_state.flags &= ~(Z_FLAG); + } else if ((b1 == 0x0a) && (b2 == 0x00)) { + /* 0f 3f 0a 00: memory size in KB */ + EAX = mem_size; + } else if ((b1 == 0x11) && (b2 == 0x00)) { + /* 0f 3f 11 00: unknown, set EAX to 0 */ + EAX = 0x00000000; + } else if ((b1 == 0x11) && (b2 == 0x01)) { + /* 0f 3f 11 00: unknown, set EAX to 0 and set zero flag */ + EAX = 0x00000000; + cpu_state.flags &= ~(Z_FLAG); + } else if ((b1 == 0x11) && (b2 == 0x02)) { + /* 0f 3f 11 02: unknown, no-op */ + } else { + /* other unknown opcodes: illegal instruction */ + cpu_state.pc = cpu_state.oldpc; - pclog("Illegal VPCEXT %08X (%02X %02X)\n", fetchdat, b1, b2); - x86illegal(); - return 0; - } + pclog("Illegal VPCEXT %08X (%02X %02X)\n", fetchdat, b1, b2); + x86illegal(); + return 0; + } - return 1; + return 1; } - -static int op0F_w_a16(uint32_t fetchdat) +static int +op0F_w_a16(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode](fetchdat >> 8); + return x86_opcodes_0f[opcode](fetchdat >> 8); } -static int op0F_l_a16(uint32_t fetchdat) +static int +op0F_l_a16(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); } -static int op0F_w_a32(uint32_t fetchdat) +static int +op0F_w_a32(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); } -static int op0F_l_a32(uint32_t fetchdat) +static int +op0F_l_a32(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } -const OpFn OP_TABLE(186_0f)[1024] = -{ +const OpFn OP_TABLE(186_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -453,10 +465,11 @@ const OpFn OP_TABLE(186_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(286_0f)[1024] = -{ +const OpFn OP_TABLE(286_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_286, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -544,10 +557,11 @@ const OpFn OP_TABLE(286_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(386_0f)[1024] = -{ +const OpFn OP_TABLE(386_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -635,10 +649,11 @@ const OpFn OP_TABLE(386_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(486_0f)[1024] = -{ +const OpFn OP_TABLE(486_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -726,10 +741,11 @@ const OpFn OP_TABLE(486_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(c486_0f)[1024] = -{ +const OpFn OP_TABLE(c486_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -817,10 +833,11 @@ const OpFn OP_TABLE(c486_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(stpc_0f)[1024] = -{ +const OpFn OP_TABLE(stpc_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -908,10 +925,11 @@ const OpFn OP_TABLE(stpc_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(ibm486_0f)[1024] = -{ +const OpFn OP_TABLE(ibm486_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -999,10 +1017,11 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(winchip_0f)[1024] = -{ +const OpFn OP_TABLE(winchip_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1090,10 +1109,11 @@ const OpFn OP_TABLE(winchip_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(winchip2_0f)[1024] = -{ +const OpFn OP_TABLE(winchip2_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, @@ -1181,10 +1201,11 @@ const OpFn OP_TABLE(winchip2_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(pentium_0f)[1024] = -{ +const OpFn OP_TABLE(pentium_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1272,11 +1293,12 @@ const OpFn OP_TABLE(pentium_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) -const OpFn OP_TABLE(c6x86_0f)[1024] = -{ +const OpFn OP_TABLE(c6x86_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1364,11 +1386,12 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; #endif -const OpFn OP_TABLE(pentiummmx_0f)[1024] = -{ +const OpFn OP_TABLE(pentiummmx_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1456,10 +1479,11 @@ const OpFn OP_TABLE(pentiummmx_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(k6_0f)[1024] = -{ +const OpFn OP_TABLE(k6_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1547,10 +1571,11 @@ const OpFn OP_TABLE(k6_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(k62_0f)[1024] = -{ +const OpFn OP_TABLE(k62_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, @@ -1638,11 +1663,12 @@ const OpFn OP_TABLE(k62_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + // clang-format on }; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) -const OpFn OP_TABLE(c6x86mx_0f)[1024] = -{ +const OpFn OP_TABLE(c6x86mx_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1730,11 +1756,12 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + // clang-format on }; #endif -const OpFn OP_TABLE(pentiumpro_0f)[1024] = -{ +const OpFn OP_TABLE(pentiumpro_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL, @@ -1822,10 +1849,11 @@ const OpFn OP_TABLE(pentiumpro_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(pentium2_0f)[1024] = -{ +const OpFn OP_TABLE(pentium2_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL, @@ -1913,10 +1941,11 @@ const OpFn OP_TABLE(pentium2_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(pentium2d_0f)[1024] = -{ +const OpFn OP_TABLE(pentium2d_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL, @@ -2004,10 +2033,11 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(186)[1024] = -{ +const OpFn OP_TABLE(186)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, @@ -2095,10 +2125,11 @@ const OpFn OP_TABLE(186)[1024] = /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, /*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, + // clang-format on }; -const OpFn OP_TABLE(286)[1024] = -{ +const OpFn OP_TABLE(286)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, @@ -2186,10 +2217,11 @@ const OpFn OP_TABLE(286)[1024] = /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, /*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, + // clang-format on }; -const OpFn OP_TABLE(386)[1024] = -{ +const OpFn OP_TABLE(386)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, @@ -2277,10 +2309,11 @@ const OpFn OP_TABLE(386)[1024] = /*d0*/ opD0_a32, opD1_l_a32, opD2_a32, opD3_l_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32, /*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX, /*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32, + // clang-format on }; -const OpFn OP_TABLE(REPE)[1024] = -{ +const OpFn OP_TABLE(REPE)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2368,10 +2401,11 @@ const OpFn OP_TABLE(REPE)[1024] = /*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // clang-format on }; -const OpFn OP_TABLE(REPNE)[1024] = -{ +const OpFn OP_TABLE(REPNE)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2459,4 +2493,5 @@ const OpFn OP_TABLE(REPNE)[1024] = /*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // clang-format on }; diff --git a/src/cpu/8080.c b/src/cpu/8080.c index c427919bc..6f3dd4267 100644 --- a/src/cpu/8080.c +++ b/src/cpu/8080.c @@ -1,19 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * 8080 CPU emulation. + * 8080 CPU emulation. * - * Authors: Cacodemon345 + * Authors: Cacodemon345 * - * Copyright 2022 Cacodemon345 + * Copyright 2022 Cacodemon345 */ - #include #include #include "cpu.h" @@ -38,16 +37,15 @@ clock_start(void) cycdiff = cycles; } - static void clock_end(void) { int diff = cycdiff - cycles; /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ - tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); + tsc += (uint64_t) diff * ((uint64_t) xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process(); } static void @@ -55,8 +53,8 @@ i8080_wait(int c, int bus) { cycles -= c; if (bus < 2) { - clock_end(); - clock_start(); + clock_end(); + clock_start(); } } @@ -73,7 +71,7 @@ readmemb(uint32_t a) } static uint8_t -ins_fetch(i8080* cpu) +ins_fetch(i8080 *cpu) { uint8_t ret = cpu->readmembyte(cpu->pmembase + cpu->pc); @@ -83,22 +81,22 @@ ins_fetch(i8080* cpu) #endif void -transfer_from_808x(i8080* cpu) +transfer_from_808x(i8080 *cpu) { - cpu->hl = BX; - cpu->bc = CX; - cpu->de = DX; - cpu->a = AL; - cpu->flags = cpu_state.flags & 0xFF; - cpu->sp = BP; - cpu->pc = cpu_state.pc; - cpu->oldpc = cpu_state.oldpc; + cpu->hl = BX; + cpu->bc = CX; + cpu->de = DX; + cpu->a = AL; + cpu->flags = cpu_state.flags & 0xFF; + cpu->sp = BP; + cpu->pc = cpu_state.pc; + cpu->oldpc = cpu_state.oldpc; cpu->pmembase = cs; cpu->dmembase = ds; } void -transfer_to_808x(i8080* cpu) +transfer_to_808x(i8080 *cpu) { BX = cpu->hl; CX = cpu->bc; @@ -106,7 +104,7 @@ transfer_to_808x(i8080* cpu) AL = cpu->a; cpu_state.flags &= 0xFF00; cpu_state.flags |= cpu->flags & 0xFF; - BP = cpu->sp; + BP = cpu->sp; cpu_state.pc = cpu->pc; } @@ -114,16 +112,31 @@ uint8_t getreg_i8080(i8080 *cpu, uint8_t reg) { uint8_t ret = 0xFF; - switch(reg) - { - case 0x0: ret = cpu->b; break; - case 0x1: ret = cpu->c; break; - case 0x2: ret = cpu->d; break; - case 0x3: ret = cpu->e; break; - case 0x4: ret = cpu->h; break; - case 0x5: ret = cpu->l; break; - case 0x6: ret = cpu->readmembyte(cpu->dmembase + cpu->sp); break; - case 0x7: ret = cpu->a; break; + switch (reg) { + case 0x0: + ret = cpu->b; + break; + case 0x1: + ret = cpu->c; + break; + case 0x2: + ret = cpu->d; + break; + case 0x3: + ret = cpu->e; + break; + case 0x4: + ret = cpu->h; + break; + case 0x5: + ret = cpu->l; + break; + case 0x6: + ret = cpu->readmembyte(cpu->dmembase + cpu->sp); + break; + case 0x7: + ret = cpu->a; + break; } return ret; } @@ -132,16 +145,31 @@ uint8_t getreg_i8080_emu(i8080 *cpu, uint8_t reg) { uint8_t ret = 0xFF; - switch(reg) - { - case 0x0: ret = CH; break; - case 0x1: ret = CL; break; - case 0x2: ret = DH; break; - case 0x3: ret = DL; break; - case 0x4: ret = BH; break; - case 0x5: ret = BL; break; - case 0x6: ret = cpu->readmembyte(cpu->dmembase + BP); break; - case 0x7: ret = AL; break; + switch (reg) { + case 0x0: + ret = CH; + break; + case 0x1: + ret = CL; + break; + case 0x2: + ret = DH; + break; + case 0x3: + ret = DL; + break; + case 0x4: + ret = BH; + break; + case 0x5: + ret = BL; + break; + case 0x6: + ret = cpu->readmembyte(cpu->dmembase + BP); + break; + case 0x7: + ret = AL; + break; } return ret; } @@ -149,57 +177,87 @@ getreg_i8080_emu(i8080 *cpu, uint8_t reg) void setreg_i8080_emu(i8080 *cpu, uint8_t reg, uint8_t val) { - switch(reg) - { - case 0x0: CH = val; break; - case 0x1: CL = val; break; - case 0x2: DH = val; break; - case 0x3: DL = val; break; - case 0x4: BH = val; break; - case 0x5: BL = val; break; - case 0x6: cpu->writemembyte(cpu->dmembase + BP, val); break; - case 0x7: AL = val; break; + switch (reg) { + case 0x0: + CH = val; + break; + case 0x1: + CL = val; + break; + case 0x2: + DH = val; + break; + case 0x3: + DL = val; + break; + case 0x4: + BH = val; + break; + case 0x5: + BL = val; + break; + case 0x6: + cpu->writemembyte(cpu->dmembase + BP, val); + break; + case 0x7: + AL = val; + break; } } void setreg_i8080(i8080 *cpu, uint8_t reg, uint8_t val) { - switch(reg) - { - case 0x0: cpu->b = val; break; - case 0x1: cpu->c = val; break; - case 0x2: cpu->d = val; break; - case 0x3: cpu->e = val; break; - case 0x4: cpu->h = val; break; - case 0x5: cpu->l = val; break; - case 0x6: cpu->writemembyte(cpu->dmembase + cpu->sp, val); break; - case 0x7: cpu->a = val; break; + switch (reg) { + case 0x0: + cpu->b = val; + break; + case 0x1: + cpu->c = val; + break; + case 0x2: + cpu->d = val; + break; + case 0x3: + cpu->e = val; + break; + case 0x4: + cpu->h = val; + break; + case 0x5: + cpu->l = val; + break; + case 0x6: + cpu->writemembyte(cpu->dmembase + cpu->sp, val); + break; + case 0x7: + cpu->a = val; + break; } } void -interpret_exec8080(i8080* cpu, uint8_t opcode) +interpret_exec8080(i8080 *cpu, uint8_t opcode) { switch (opcode) { case 0x00: - { - break; - } + { + break; + } } } /* Actually implement i8080 emulation. */ void -exec8080(i8080* cpu, int cycs) +exec8080(i8080 *cpu, int cycs) { #ifdef UNUSED_8080_VARS - uint8_t temp = 0, temp2; - uint8_t old_af; - uint8_t handled = 0; + uint8_t temp = 0, temp2; + uint8_t old_af; + uint8_t handled = 0; uint16_t addr, tempw; uint16_t new_ip; - int bits; + int bits; #endif cycles += cycs; @@ -209,17 +267,18 @@ exec8080(i8080* cpu, int cycs) if (!repeating) { cpu->oldpc = cpu->pc; - opcode = cpu->fetchinstruction(cpu); - oldc = cpu->flags & C_FLAG_I8080; + opcode = cpu->fetchinstruction(cpu); + oldc = cpu->flags & C_FLAG_I8080; i8080_wait(1, 0); } completed = 1; if (completed) { - repeating = 0; - in_rep = 0; + repeating = 0; + in_rep = 0; rep_c_flag = 0; cpu->endclock(); - if (cpu->checkinterrupts) cpu->checkinterrupts(); + if (cpu->checkinterrupts) + cpu->checkinterrupts(); } } -} \ No newline at end of file +} diff --git a/src/cpu/808x.c b/src/cpu/808x.c index ade656dd8..b2859153a 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * 808x CPU emulation, mostly ported from reenigne's XTCE, which - * is cycle-accurate. + * 808x CPU emulation, mostly ported from reenigne's XTCE, which + * is cycle-accurate. * - * Authors: Andrew Jenner, - * Miran Grca, + * Authors: Andrew Jenner, + * Miran Grca, * - * Copyright 2015-2020 Andrew Jenner. - * Copyright 2016-2020 Miran Grca. + * Copyright 2015-2020 Andrew Jenner. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -494,7 +494,7 @@ pfq_fetchw(void) } static uint16_t -pfq_fetch() +pfq_fetch(void) { if (opcode & 1) return pfq_fetchw(); @@ -520,7 +520,7 @@ pfq_add(int c, int add) /* Clear the prefetch queue - called on reset and on anything that affects either CS or IP. */ static void -pfq_clear() +pfq_clear(void) { pfq_pos = 0; prefetching = 0; @@ -1085,9 +1085,9 @@ rep_action(int bits) access(71, bits); pfq_clear(); if (is_nec && (ovr_seg != NULL)) - set_ip(cpu_state.pc - 3); + set_ip(cpu_state.pc - 3); else - set_ip(cpu_state.pc - 2); + set_ip(cpu_state.pc - 2); t = 0; } if (t == 0) { @@ -1683,7 +1683,7 @@ execx86(int cycs) // pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode); if (is186) { switch (opcode) { - case 0x60: /*PUSHA/PUSH R*/ + case 0x60: /*PUSHA/PUSH R*/ orig_sp = SP; wait(1, 0); push(&AX); @@ -1696,12 +1696,12 @@ execx86(int cycs) push(&DI); handled = 1; break; - case 0x61: /*POPA/POP R*/ + case 0x61: /*POPA/POP R*/ wait(9, 0); - DI = pop(); - SI = pop(); - BP = pop(); - (void) pop(); /* former orig_sp */ + DI = pop(); + SI = pop(); + BP = pop(); + (void) pop(); /* former orig_sp */ BX = pop(); DX = pop(); CX = pop(); @@ -1710,9 +1710,9 @@ execx86(int cycs) break; case 0x62: /* BOUND r/m */ - lowbound = 0; + lowbound = 0; highbound = 0; - regval = 0; + regval = 0; do_mod_rm(); lowbound = readmemw(easeg, cpu_state.eaaddr); @@ -1733,7 +1733,7 @@ execx86(int cycs) in_rep = (opcode == 0x64 ? 1 : 2); rep_c_flag = 1; completed = 0; - handled = 1; + handled = 1; } break; @@ -1746,7 +1746,7 @@ execx86(int cycs) case 0x69: immediate = 0; - bits = 16; + bits = 16; do_mod_rm(); read_ea(0, 16); immediate = pfq_fetchw(); @@ -1764,7 +1764,7 @@ execx86(int cycs) case 0x6b: /* IMUL reg16,reg16/mem16,imm8 */ immediate = 0; - bits = 16; + bits = 16; do_mod_rm(); read_ea(0, 16); immediate = pfq_fetchb(); @@ -1805,13 +1805,13 @@ execx86(int cycs) case 0x6e: case 0x6f: /* OUTM DW, src/OUTS DX, src */ dest_seg = ovr_seg ? *ovr_seg : ds; - bits = 8 << (opcode & 1); - handled = 1; + bits = 8 << (opcode & 1); + handled = 1; if (!repeating) wait(2, 0); if (rep_action(bits)) - break; + break; else if (!repeating) wait(7, 0); @@ -1832,9 +1832,9 @@ execx86(int cycs) case 0xc8: /* ENTER/PREPARE */ tempw_int = 0; - size = pfq_fetchw(); - nests = pfq_fetchb(); - i = 0; + size = pfq_fetchw(); + nests = pfq_fetchb(); + i = 0; push(&BP); tempw_int = SP; @@ -1984,7 +1984,7 @@ execx86(int cycs) handled = 1; break; - case 0x2a: /* ROR4 r/m */ + case 0x2a: /* ROR4 r/m */ do_mod_rm(); wait(21, 0); @@ -2081,10 +2081,10 @@ execx86(int cycs) odd = !!(CL % 2); zero = 1; nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; wait(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { @@ -2116,10 +2116,10 @@ execx86(int cycs) odd = !!(CL % 2); zero = 1; nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; wait(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { @@ -2151,10 +2151,10 @@ execx86(int cycs) odd = !!(CL % 2); zero = 1; nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; wait(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { @@ -2206,7 +2206,7 @@ execx86(int cycs) } } setr8(cpu_rm, bit_offset); - + handled = 1; break; @@ -2501,9 +2501,9 @@ execx86(int cycs) wait(1, 0); break; - case 0x60: /*JO alias*/ - case 0x70: /*JO*/ - case 0x61: /*JNO alias*/ + case 0x60: /*JO alias*/ + case 0x70: /*JO*/ + case 0x61: /*JNO alias*/ case 0x71: /*JNO*/ jcc(opcode, cpu_state.flags & V_FLAG); break; @@ -2525,15 +2525,15 @@ execx86(int cycs) case 0x77: /*JNBE*/ jcc(opcode, cpu_state.flags & (C_FLAG | Z_FLAG)); break; - case 0x68: /*JS alias*/ - case 0x78: /*JS*/ - case 0x69: /*JNS alias*/ + case 0x68: /*JS alias*/ + case 0x78: /*JS*/ + case 0x69: /*JNS alias*/ case 0x79: /*JNS*/ jcc(opcode, cpu_state.flags & N_FLAG); break; - case 0x6A: /*JP alias*/ - case 0x7A: /*JP*/ - case 0x6B: /*JNP alias*/ + case 0x6A: /*JP alias*/ + case 0x7A: /*JP*/ + case 0x6B: /*JNP alias*/ case 0x7B: /*JNP*/ jcc(opcode, cpu_state.flags & P_FLAG); break; diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index c91bcbe78..e61d4bfcf 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c diff --git a/src/cpu/codegen_public.h b/src/cpu/codegen_public.h index 18f0618b8..36393296e 100644 --- a/src/cpu/codegen_public.h +++ b/src/cpu/codegen_public.h @@ -36,29 +36,27 @@ #define _CODEGEN_PUBLIC_H_ #ifndef USE_NEW_DYNAREC -#define PAGE_MASK_INDEX_MASK 3 -#define PAGE_MASK_INDEX_SHIFT 10 -#define PAGE_MASK_SHIFT 4 +# define PAGE_MASK_INDEX_MASK 3 +# define PAGE_MASK_INDEX_SHIFT 10 +# define PAGE_MASK_SHIFT 4 #else -#define PAGE_MASK_SHIFT 6 +# define PAGE_MASK_SHIFT 6 #endif #define PAGE_MASK_MASK 63 #ifdef USE_NEW_DYNAREC -#define BLOCK_PC_INVALID 0xffffffff -#define BLOCK_INVALID 0 +# define BLOCK_PC_INVALID 0xffffffff +# define BLOCK_INVALID 0 #endif - -extern void codegen_init(); +extern void codegen_init(void); #ifdef USE_NEW_DYNAREC -extern void codegen_close(); +extern void codegen_close(void); #endif -extern void codegen_flush(); - +extern void codegen_flush(void); /*Current physical page of block being recompiled. -1 if no recompilation taking place */ -extern uint32_t recomp_page; -extern int codegen_in_recompile; +extern uint32_t recomp_page; +extern int codegen_in_recompile; #endif diff --git a/src/cpu/codegen_timing_486.c b/src/cpu/codegen_timing_486.c index ce451421d..2fe5ce417 100644 --- a/src/cpu/codegen_timing_486.c +++ b/src/cpu/codegen_timing_486.c @@ -283,12 +283,12 @@ static inline int COUNT(int *c, int op_32) return *c; } -void codegen_timing_486_block_start() +void codegen_timing_486_block_start(void) { regmask_modified = 0; } -void codegen_timing_486_start() +void codegen_timing_486_start(void) { timing_count = 0; last_prefix = 0; @@ -406,7 +406,7 @@ void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uin regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_486_block_end() +void codegen_timing_486_block_end(void) { } diff --git a/src/cpu/codegen_timing_686.c b/src/cpu/codegen_timing_686.c index cde59d9cb..9752b24c4 100644 --- a/src/cpu/codegen_timing_686.c +++ b/src/cpu/codegen_timing_686.c @@ -774,13 +774,13 @@ static inline int COUNT(uint32_t c, int op_32) return c & CYCLES_MASK; } -void codegen_timing_686_block_start() +void codegen_timing_686_block_start(void) { prev_full = decode_delay = 0; regmask_modified = last_regmask_modified = 0; } -void codegen_timing_686_start() +void codegen_timing_686_start(void) { decode_delay = 0; last_prefix = 0; @@ -1036,7 +1036,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uin } } -void codegen_timing_686_block_end() +void codegen_timing_686_block_end(void) { if (prev_full) { diff --git a/src/cpu/codegen_timing_common.h b/src/cpu/codegen_timing_common.h index a3faca27d..679997802 100644 --- a/src/cpu/codegen_timing_common.h +++ b/src/cpu/codegen_timing_common.h @@ -3,11 +3,11 @@ /*Instruction has input dependency on register in REG field*/ #define SRCDEP_REG (1ull << 0) /*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1ull << 1) +#define SRCDEP_RM (1ull << 1) /*Instruction modifies register in REG field*/ #define DSTDEP_REG (1ull << 2) /*Instruction modifies register in R/M field*/ -#define DSTDEP_RM (1ull << 3) +#define DSTDEP_RM (1ull << 3) #define SRCDEP_SHIFT 4 #define DSTDEP_SHIFT 12 @@ -40,48 +40,45 @@ /*Instruction is MMX shift or pack/unpack instruction*/ #define MMX_SHIFTPACK (1ull << 22) /*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1ull << 23) +#define MMX_MULTIPLY (1ull << 23) /*Instruction pops the FPU stack*/ -#define FPU_POP (1ull << 24) +#define FPU_POP (1ull << 24) /*Instruction pops the FPU stack twice*/ -#define FPU_POP2 (1ull << 25) +#define FPU_POP2 (1ull << 25) /*Instruction pushes onto the FPU stack*/ -#define FPU_PUSH (1ull << 26) +#define FPU_PUSH (1ull << 26) /*Instruction writes to ST(0)*/ -#define FPU_WRITE_ST0 (1ull << 27) +#define FPU_WRITE_ST0 (1ull << 27) /*Instruction reads from ST(0)*/ -#define FPU_READ_ST0 (1ull << 28) +#define FPU_READ_ST0 (1ull << 28) /*Instruction reads from and writes to ST(0)*/ -#define FPU_RW_ST0 (3ull << 27) +#define FPU_RW_ST0 (3ull << 27) /*Instruction reads from ST(1)*/ -#define FPU_READ_ST1 (1ull << 29) +#define FPU_READ_ST1 (1ull << 29) /*Instruction writes to ST(1)*/ -#define FPU_WRITE_ST1 (1ull << 30) +#define FPU_WRITE_ST1 (1ull << 30) /*Instruction reads from and writes to ST(1)*/ -#define FPU_RW_ST1 (3ull << 29) +#define FPU_RW_ST1 (3ull << 29) /*Instruction reads from ST(reg)*/ -#define FPU_READ_STREG (1ull << 31) +#define FPU_READ_STREG (1ull << 31) /*Instruction writes to ST(reg)*/ #define FPU_WRITE_STREG (1ull << 32) /*Instruction reads from and writes to ST(reg)*/ -#define FPU_RW_STREG (3ull << 31) +#define FPU_RW_STREG (3ull << 31) -#define FPU_FXCH (1ull << 33) +#define FPU_FXCH (1ull << 33) +#define HAS_IMM8 (1ull << 34) +#define HAS_IMM1632 (1ull << 35) -#define HAS_IMM8 (1ull << 34) -#define HAS_IMM1632 (1ull << 35) - - -#define REGMASK_IMPL_ESP (1 << 8) +#define REGMASK_IMPL_ESP (1 << 8) #define REGMASK_SHIFTPACK (1 << 9) #define REGMASK_MULTIPLY (1 << 9) - extern uint64_t opcode_deps[256]; extern uint64_t opcode_deps_mod3[256]; extern uint64_t opcode_deps_0f[256]; @@ -119,114 +116,116 @@ extern uint64_t opcode_deps_81_mod3[8]; extern uint64_t opcode_deps_8x[8]; extern uint64_t opcode_deps_8x_mod3[8]; - - -static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) +static inline uint32_t +get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) { - uint32_t addr_regmask = 0; + uint32_t addr_regmask = 0; - if (data & MODRM) - { - uint8_t modrm = fetchdat & 0xff; + if (data & MODRM) { + uint8_t modrm = fetchdat & 0xff; - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 0x7) == 4) - { - uint8_t sib = (fetchdat >> 8) & 0xff; + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 0x7) == 4) { + uint8_t sib = (fetchdat >> 8) & 0xff; - if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) - { - addr_regmask = 1 << (sib & 7); - if ((sib & 0x38) != 0x20) - addr_regmask |= 1 << ((sib >> 3) & 7); - } - } - else if ((modrm & 0xc7) != 5) - { - addr_regmask = 1 << (modrm & 7); - } - } - else - { - if ((modrm & 0xc7) != 0x06) - { - switch (modrm & 7) - { - case 0: addr_regmask = REG_BX | REG_SI; break; - case 1: addr_regmask = REG_BX | REG_DI; break; - case 2: addr_regmask = REG_BP | REG_SI; break; - case 3: addr_regmask = REG_BP | REG_DI; break; - case 4: addr_regmask = REG_SI; break; - case 5: addr_regmask = REG_DI; break; - case 6: addr_regmask = REG_BP; break; - case 7: addr_regmask = REG_BX; break; - } - } - } + if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) { + addr_regmask = 1 << (sib & 7); + if ((sib & 0x38) != 0x20) + addr_regmask |= 1 << ((sib >> 3) & 7); + } + } else if ((modrm & 0xc7) != 5) { + addr_regmask = 1 << (modrm & 7); } + } else { + if ((modrm & 0xc7) != 0x06) { + switch (modrm & 7) { + case 0: + addr_regmask = REG_BX | REG_SI; + break; + case 1: + addr_regmask = REG_BX | REG_DI; + break; + case 2: + addr_regmask = REG_BP | REG_SI; + break; + case 3: + addr_regmask = REG_BP | REG_DI; + break; + case 4: + addr_regmask = REG_SI; + break; + case 5: + addr_regmask = REG_DI; + break; + case 6: + addr_regmask = REG_BP; + break; + case 7: + addr_regmask = REG_BX; + break; + } + } + } } + } - if (data & IMPL_ESP) - addr_regmask |= REGMASK_IMPL_ESP; + if (data & IMPL_ESP) + addr_regmask |= REGMASK_IMPL_ESP; - return addr_regmask; + return addr_regmask; } -static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32) +static inline uint32_t +get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32) { - uint32_t mask = 0; - if (data & SRCDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & SRCDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> SRCDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; + uint32_t mask = 0; + if (data & SRCDEP_REG) { + int reg = (fetchdat >> 3) & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + if (data & SRCDEP_RM) { + int reg = fetchdat & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + mask |= ((data >> SRCDEP_SHIFT) & 0xff); + if (data & MMX_SHIFTPACK) + mask |= REGMASK_SHIFTPACK; + if (data & MMX_MULTIPLY) + mask |= REGMASK_MULTIPLY; - mask |= get_addr_regmask(data, fetchdat, op_32); + mask |= get_addr_regmask(data, fetchdat, op_32); - return mask; + return mask; } -static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) +static inline uint32_t +get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) { - uint32_t mask = 0; - if (data & DSTDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & DSTDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> DSTDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; - if (data & IMPL_ESP) - mask |= REGMASK_IMPL_ESP | (1 << REG_ESP); + uint32_t mask = 0; + if (data & DSTDEP_REG) { + int reg = (fetchdat >> 3) & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + if (data & DSTDEP_RM) { + int reg = fetchdat & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + mask |= ((data >> DSTDEP_SHIFT) & 0xff); + if (data & MMX_SHIFTPACK) + mask |= REGMASK_SHIFTPACK; + if (data & MMX_MULTIPLY) + mask |= REGMASK_MULTIPLY; + if (data & IMPL_ESP) + mask |= REGMASK_IMPL_ESP | (1 << REG_ESP); - return mask; + return mask; } diff --git a/src/cpu/codegen_timing_k6.c b/src/cpu/codegen_timing_k6.c index 66ec33052..6bb472144 100644 --- a/src/cpu/codegen_timing_k6.c +++ b/src/cpu/codegen_timing_k6.c @@ -1858,7 +1858,7 @@ static int fpu_st_timestamp[8]; dependent uop chains*/ static int last_uop_timestamp = 0; -void decode_flush() +void decode_flush(void) { int c; int uop_timestamp = 0; @@ -2112,7 +2112,7 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u } } -void codegen_timing_k6_block_start() +void codegen_timing_k6_block_start(void) { int c; @@ -2136,7 +2136,7 @@ void codegen_timing_k6_block_start() fpu_st_timestamp[c] = 0; } -void codegen_timing_k6_start() +void codegen_timing_k6_start(void) { if (cpu_s->cpu_type == CPU_K6) { @@ -2324,7 +2324,7 @@ void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); } -void codegen_timing_k6_block_end() +void codegen_timing_k6_block_end(void) { if (decode_buffer.nr_uops) { @@ -2334,7 +2334,7 @@ void codegen_timing_k6_block_end() } } -int codegen_timing_k6_jump_cycles() +int codegen_timing_k6_jump_cycles(void) { if (decode_buffer.nr_uops) return 1; diff --git a/src/cpu/codegen_timing_p6.c b/src/cpu/codegen_timing_p6.c index 00f5bfb24..19fa07de1 100644 --- a/src/cpu/codegen_timing_p6.c +++ b/src/cpu/codegen_timing_p6.c @@ -1691,7 +1691,7 @@ static int fpu_st_timestamp[8]; dependent uop chains*/ static int last_uop_timestamp = 0; -void decode_flush_p6() +void decode_flush_p6(void) { int c; int start_timestamp, uop_timestamp = 0; @@ -1926,7 +1926,7 @@ static void decode_instruction(const macro_op_t *ins, uint64_t deps, uint32_t fe } } -void codegen_timing_p6_block_start() +void codegen_timing_p6_block_start(void) { int c; @@ -1946,7 +1946,7 @@ void codegen_timing_p6_block_start() fpu_st_timestamp[c] = 0; } -void codegen_timing_p6_start() +void codegen_timing_p6_start(void) { if (cpu_s->cpu_type == CPU_PENTIUMPRO) { @@ -2083,7 +2083,7 @@ void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); } -void codegen_timing_p6_block_end() +void codegen_timing_p6_block_end(void) { if (decode_buffer.nr_uops) { @@ -2093,7 +2093,7 @@ void codegen_timing_p6_block_end() } } -int codegen_timing_p6_jump_cycles() +int codegen_timing_p6_jump_cycles(void) { if (decode_buffer.nr_uops) return 1; diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c index 263608682..232455f6d 100644 --- a/src/cpu/codegen_timing_pentium.c +++ b/src/cpu/codegen_timing_pentium.c @@ -931,12 +931,12 @@ static inline int codegen_timing_instr_length(uint64_t timing, uint32_t fetchdat return len; } -void codegen_timing_pentium_block_start() +void codegen_timing_pentium_block_start(void) { u_pipe_full = decode_delay = decode_delay_offset = 0; } -void codegen_timing_pentium_start() +void codegen_timing_pentium_start(void) { last_prefix = 0; prefixes = 0; @@ -1296,7 +1296,7 @@ nopair: addr_regmask = 0; } -void codegen_timing_pentium_block_end() +void codegen_timing_pentium_block_end(void) { if (u_pipe_full) { diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c index c945d7f21..a1ee02b63 100644 --- a/src/cpu/codegen_timing_winchip.c +++ b/src/cpu/codegen_timing_winchip.c @@ -283,12 +283,12 @@ static inline int COUNT(int *c, int op_32) return *c; } -void codegen_timing_winchip_block_start() +void codegen_timing_winchip_block_start(void) { regmask_modified = 0; } -void codegen_timing_winchip_start() +void codegen_timing_winchip_start(void) { timing_count = 0; last_prefix = 0; @@ -406,7 +406,7 @@ void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_winchip_block_end() +void codegen_timing_winchip_block_end(void) { } diff --git a/src/cpu/codegen_timing_winchip2.c b/src/cpu/codegen_timing_winchip2.c index 38c8924d4..f96304072 100644 --- a/src/cpu/codegen_timing_winchip2.c +++ b/src/cpu/codegen_timing_winchip2.c @@ -541,14 +541,14 @@ static void codegen_instruction(uint32_t *timings, uint64_t *deps, uint8_t opcod } } -static void codegen_timing_winchip2_block_start() +static void codegen_timing_winchip2_block_start(void) { regmask_modified = 0; decode_delay = decode_delay_offset = 0; u_pipe_full = 0; } -static void codegen_timing_winchip2_start() +static void codegen_timing_winchip2_start(void) { timing_count = 0; last_prefix = 0; @@ -719,7 +719,7 @@ static void codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, in regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -static void codegen_timing_winchip2_block_end() +static void codegen_timing_winchip2_block_end(void) { if (u_pipe_full) { diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index ea90814c9..d667c743e 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -61,6 +61,7 @@ enum { CPUID_AMDSEP = (1 << 10), CPUID_SEP = (1 << 11), CPUID_MTRR = (1 << 12), + CPUID_PGE = (1 << 13), CPUID_MCA = (1 << 14), CPUID_CMOV = (1 << 15), CPUID_MMX = (1 << 23), @@ -1169,8 +1170,10 @@ cpu_set(void) #endif if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) { - x86_opcodes_3DNOW = ops_3DNOWE; + x86_opcodes_3DNOW = ops_3DNOWE; +#ifdef USE_DYNAREC x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOWE; +#endif } timing_rr = 1; /* register dest - register src */ @@ -1296,7 +1299,7 @@ cpu_set(void) if (cpu_s->cpu_type >= CPU_PENTIUM2) cpu_features |= CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE | CR4_PGE; if (cpu_s->cpu_type == CPU_PENTIUM2D) cpu_CR4_mask |= CR4_OSFXSR; @@ -1957,7 +1960,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; @@ -1975,7 +1978,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; @@ -1993,7 +1996,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index ae24c44d5..a28618fe1 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -35,9 +35,9 @@ enum { enum { CPU_8088 = 1, /* 808x class CPUs */ CPU_8086, - CPU_V20, /* NEC 808x class CPUs */ + CPU_V20, /* NEC 808x class CPUs */ CPU_V30, - CPU_188, /* 18x class CPUs */ + CPU_188, /* 18x class CPUs */ CPU_186, CPU_286, /* 286 class CPUs */ CPU_386SX, /* 386 class CPUs */ @@ -195,6 +195,7 @@ typedef struct { #define CR4_PVI (1 << 1) #define CR4_PSE (1 << 4) #define CR4_PAE (1 << 5) +#define CR4_PGE (1 << 7) #define CPL ((cpu_state.seg_cs.access >> 5) & 3) @@ -740,7 +741,7 @@ extern void cpu_fast_off_advance(void); extern void cpu_fast_off_period_set(uint16_t vla, double period); extern void cpu_fast_off_reset(void); -extern void smi_raise(); -extern void nmi_raise(); +extern void smi_raise(void); +extern void nmi_raise(void); #endif /*EMU_CPU_H*/ diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 0e805a702..6fc922b1e 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1,28 +1,28 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Define all known processor types. + * Define all known processor types. * * * - * Authors: Sarah Walker, - * leilei, - * Miran Grca, - * Fred N. van Kempen, - * RichardG, - * dob205, + * Authors: Sarah Walker, + * leilei, + * Miran Grca, + * Fred N. van Kempen, + * RichardG, + * dob205, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 leilei. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2020 RichardG. - * Copyright 2021 dob205. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 leilei. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2020 RichardG. + * Copyright 2021 dob205. */ #include #include @@ -32,51 +32,44 @@ #include "cpu.h" #include <86box/machine.h> -FPU fpus_none[] = -{ - {"None", "none", FPU_NONE}, - {NULL, NULL, 0} +FPU fpus_none[] = { + {"None", "none", FPU_NONE}, + { NULL, NULL, 0 } }; -FPU fpus_8088[] = -{ - {"None", "none", FPU_NONE}, - {"8087", "8087", FPU_8087}, - {NULL, NULL, 0} +FPU fpus_8088[] = { + {"None", "none", FPU_NONE}, + { "8087", "8087", FPU_8087}, + { NULL, NULL, 0 } }; -FPU fpus_80186[] = -{ - {"None", "none", FPU_NONE}, - {"8087", "8087", FPU_8087}, - {"80187", "80187", FPU_80187}, - {NULL, NULL, 0} +FPU fpus_80186[] = { + {"None", "none", FPU_NONE }, + { "8087", "8087", FPU_8087 }, + { "80187", "80187", FPU_80187}, + { NULL, NULL, 0 } }; -FPU fpus_80286[] = -{ - {"None", "none", FPU_NONE}, - {"287", "287", FPU_287}, - {"287XL","287xl", FPU_287XL}, - {NULL, NULL, 0} +FPU fpus_80286[] = { + {"None", "none", FPU_NONE }, + { "287", "287", FPU_287 }, + { "287XL", "287xl", FPU_287XL}, + { NULL, NULL, 0 } }; -FPU fpus_80386[] = -{ - {"None", "none", FPU_NONE}, - {"387", "387", FPU_387}, - {NULL, NULL, 0} +FPU fpus_80386[] = { + {"None", "none", FPU_NONE}, + { "387", "387", FPU_387 }, + { NULL, NULL, 0 } }; -FPU fpus_486sx[] = -{ - {"None", "none", FPU_NONE}, - {"487SX","487sx", FPU_487SX}, - {NULL, NULL, 0} +FPU fpus_486sx[] = { + {"None", "none", FPU_NONE }, + { "487SX", "487sx", FPU_487SX}, + { NULL, NULL, 0 } }; -FPU fpus_internal[] = -{ - {"Internal", "internal", FPU_INTERNAL}, - {NULL, NULL, 0} +FPU fpus_internal[] = { + {"Internal", "internal", FPU_INTERNAL}, + { NULL, NULL, 0 } }; - const cpu_family_t cpu_families[] = { + // clang-format off { .package = CPU_PKG_8088, .manufacturer = "Intel", @@ -140,8 +133,8 @@ const cpu_family_t cpu_families[] = { .name = "V20", .internal_name = "necv20", .cpus = (const CPU[]) { - {"5", CPU_V20, fpus_8088, 5000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8", CPU_V20, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, + {"4.77", CPU_V20, fpus_8088, 4772728, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, + {"7.16", CPU_V20, fpus_8088, 7159092, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, {"10", CPU_V20, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, {"12", CPU_V20, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, {"16", CPU_V20, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2}, @@ -458,7 +451,7 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { - .package = CPU_PKG_SOCKET1 | CPU_PKG_SOCKET3_PC330, /*OEM versions are 3.3V, Retail versions are 3.3V with a 5V regulator for installation in older boards. hey are functionally identical*/ + .package = CPU_PKG_SOCKET1 | CPU_PKG_SOCKET3_PC330, /*OEM versions are 3.3V, Retail versions are 3.3V with a 5V regulator for installation in older boards. They are functionally identical*/ .manufacturer = "Intel", .name = "iDX4", .internal_name = "idx4", @@ -1146,958 +1139,958 @@ const cpu_family_t cpu_families[] = { }, { .package = 0, } + // clang-format on }; /* Legacy CPU tables for backwards compatibility. */ static const cpu_legacy_table_t cpus_8088[] = { - {"8088", 4772728, 1}, - {"8088", 7159092, 1}, - {"8088", 8000000, 1}, - {"8088", 10000000, 1}, - {"8088", 12000000, 1}, - {"8088", 16000000, 1}, - {NULL, 0, 0} + {"8088", 4772728, 1}, + { "8088", 7159092, 1}, + { "8088", 8000000, 1}, + { "8088", 10000000, 1}, + { "8088", 12000000, 1}, + { "8088", 16000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_pcjr[] = { {"8088", 4772728, 1}, - {NULL, 0, 0} + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_europc[] = { - {"8088_europc", 4772728, 1}, - {"8088_europc", 7159092, 1}, - {"8088_europc", 9545456, 1}, - {NULL, 0, 0} + {"8088_europc", 4772728, 1}, + { "8088_europc", 7159092, 1}, + { "8088_europc", 9545456, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_8086[] = { - {"8086", 7159092, 1}, - {"8086", 8000000, 1}, - {"8086", 9545456, 1}, - {"8086", 10000000, 1}, - {"8086", 12000000, 1}, - {"8086", 16000000, 1}, - {NULL, 0, 0} + {"8086", 7159092, 1}, + { "8086", 8000000, 1}, + { "8086", 9545456, 1}, + { "8086", 10000000, 1}, + { "8086", 12000000, 1}, + { "8086", 16000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_pc1512[] = { {"8086", 8000000, 1}, - {NULL, 0, 0} + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_286[] = { - {"286", 6000000, 1}, - {"286", 8000000, 1}, - {"286", 10000000, 1}, - {"286", 12500000, 1}, - {"286", 16000000, 1}, - {"286", 20000000, 1}, - {"286", 25000000, 1}, - {NULL, 0, 0} + {"286", 6000000, 1}, + { "286", 8000000, 1}, + { "286", 10000000, 1}, + { "286", 12500000, 1}, + { "286", 16000000, 1}, + { "286", 20000000, 1}, + { "286", 25000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ibmat[] = { - {"286", 6000000, 1}, - {"286", 8000000, 1}, - {NULL, 0, 0} + {"286", 6000000, 1}, + { "286", 8000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ibmxt286[] = { {"286", 6000000, 1}, - {NULL, 0, 0} + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ps1_m2011[] = { {"286", 10000000, 1}, - {NULL, 0, 0} + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ps2_m30_286[] = { - {"286", 10000000, 1}, - {"286", 12500000, 1}, - {"286", 16000000, 1}, - {"286", 20000000, 1}, - {"286", 25000000, 1}, - {NULL, 0, 0} + {"286", 10000000, 1}, + { "286", 12500000, 1}, + { "286", 16000000, 1}, + { "286", 20000000, 1}, + { "286", 25000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_i386SX[] = { - {"i386sx", 16000000, 1}, - {"i386sx", 20000000, 1}, - {"i386sx", 25000000, 1}, - {"i386sx", 33333333, 1}, - {"i386sx", 40000000, 1}, - {NULL, 0, 0} + {"i386sx", 16000000, 1}, + { "i386sx", 20000000, 1}, + { "i386sx", 25000000, 1}, + { "i386sx", 33333333, 1}, + { "i386sx", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_i386DX[] = { - {"i386dx", 16000000, 1}, - {"i386dx", 20000000, 1}, - {"i386dx", 25000000, 1}, - {"i386dx", 33333333, 1}, - {"i386dx", 40000000, 1}, - {"rapidcad", 25000000, 1}, - {"rapidcad", 33333333, 1}, - {"rapidcad", 40000000, 1}, - {NULL, 0, 0} + {"i386dx", 16000000, 1}, + { "i386dx", 20000000, 1}, + { "i386dx", 25000000, 1}, + { "i386dx", 33333333, 1}, + { "i386dx", 40000000, 1}, + { "rapidcad", 25000000, 1}, + { "rapidcad", 33333333, 1}, + { "rapidcad", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_Am386SX[] = { - {"am386sx", 16000000, 1}, - {"am386sx", 20000000, 1}, - {"am386sx", 25000000, 1}, - {"am386sx", 33333333, 1}, - {"am386sx", 40000000, 1}, - {NULL, 0, 0} + {"am386sx", 16000000, 1}, + { "am386sx", 20000000, 1}, + { "am386sx", 25000000, 1}, + { "am386sx", 33333333, 1}, + { "am386sx", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_Am386DX[] = { - {"am386dx", 25000000, 1}, - {"am386dx", 33333333, 1}, - {"am386dx", 40000000, 1}, - {NULL, 0, 0} + {"am386dx", 25000000, 1}, + { "am386dx", 33333333, 1}, + { "am386dx", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ALiM6117[] = { - {"m6117", 33333333, 1}, - {"m6117", 40000000, 1}, - {NULL, 0, 0} + {"m6117", 33333333, 1}, + { "m6117", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_486SLC[] = { - {"cx486slc", 20000000, 1}, - {"cx486slc", 25000000, 1}, - {"cx486slc", 33333333, 1}, - {"cx486srx2", 32000000, 2}, - {"cx486srx2", 40000000, 2}, - {"cx486srx2", 50000000, 2}, - {NULL, 0, 0} + {"cx486slc", 20000000, 1}, + { "cx486slc", 25000000, 1}, + { "cx486slc", 33333333, 1}, + { "cx486srx2", 32000000, 2}, + { "cx486srx2", 40000000, 2}, + { "cx486srx2", 50000000, 2}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_IBM486SLC[] = { - {"ibm486slc", 33333333, 1}, - {"ibm486slc2", 40000000, 2}, - {"ibm486slc2", 50000000, 2}, - {"ibm486slc2", 66666666, 2}, - {"ibm486slc3", 60000000, 3}, - {"ibm486slc3", 75000000, 3}, - {"ibm486slc3", 100000000, 3}, - {NULL, 0, 0} + {"ibm486slc", 33333333, 1}, + { "ibm486slc2", 40000000, 2}, + { "ibm486slc2", 50000000, 2}, + { "ibm486slc2", 66666666, 2}, + { "ibm486slc3", 60000000, 3}, + { "ibm486slc3", 75000000, 3}, + { "ibm486slc3", 100000000, 3}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_IBM486BL[] = { - {"ibm486bl2", 50000000, 2}, - {"ibm486bl2", 66666666, 2}, - {"ibm486bl3", 75000000, 3}, - {"ibm486bl3", 100000000, 3}, - {NULL, 0, 0} + {"ibm486bl2", 50000000, 2}, + { "ibm486bl2", 66666666, 2}, + { "ibm486bl3", 75000000, 3}, + { "ibm486bl3", 100000000, 3}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_486DLC[] = { - {"cx486dlc", 25000000, 1}, - {"cx486dlc", 33333333, 1}, - {"cx486dlc", 40000000, 1}, - {"cx486drx2", 32000000, 2}, - {"cx486drx2", 40000000, 2}, - {"cx486drx2", 50000000, 2}, - {"cx486drx2", 66666666, 2}, - {NULL, 0, 0} + {"cx486dlc", 25000000, 1}, + { "cx486dlc", 33333333, 1}, + { "cx486dlc", 40000000, 1}, + { "cx486drx2", 32000000, 2}, + { "cx486drx2", 40000000, 2}, + { "cx486drx2", 50000000, 2}, + { "cx486drx2", 66666666, 2}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_i486S1[] = { - {"i486sx", 16000000, 1}, - {"i486sx", 20000000, 1}, - {"i486sx", 25000000, 1}, - {"i486sx", 33333333, 1}, - {"i486sx2", 50000000, 2}, - {"i486sx2", 66666666, 2}, - {"i486dx", 25000000, 1}, - {"i486dx", 33333333, 1}, - {"i486dx", 50000000, 1}, - {"i486dx2", 40000000, 2}, - {"i486dx2", 50000000, 2}, - {"i486dx2", 66666666, 2}, - {"idx4_od", 75000000, 3}, - {"idx4_od", 100000000, 3}, - {NULL, 0, 0} + {"i486sx", 16000000, 1}, + { "i486sx", 20000000, 1}, + { "i486sx", 25000000, 1}, + { "i486sx", 33333333, 1}, + { "i486sx2", 50000000, 2}, + { "i486sx2", 66666666, 2}, + { "i486dx", 25000000, 1}, + { "i486dx", 33333333, 1}, + { "i486dx", 50000000, 1}, + { "i486dx2", 40000000, 2}, + { "i486dx2", 50000000, 2}, + { "i486dx2", 66666666, 2}, + { "idx4_od", 75000000, 3}, + { "idx4_od", 100000000, 3}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_Am486S1[] = { - {"am486sx", 33333333, 1}, - {"am486sx", 40000000, 1}, - {"am486sx2", 50000000, 2}, - {"am486sx2", 66666666, 2}, - {"am486dx", 33333333, 1}, - {"am486dx", 40000000, 1}, - {"am486dx2", 50000000, 2}, - {"am486dx2", 66666666, 2}, - {"am486dx2", 80000000, 2}, - {NULL, 0, 0} + {"am486sx", 33333333, 1}, + { "am486sx", 40000000, 1}, + { "am486sx2", 50000000, 2}, + { "am486sx2", 66666666, 2}, + { "am486dx", 33333333, 1}, + { "am486dx", 40000000, 1}, + { "am486dx2", 50000000, 2}, + { "am486dx2", 66666666, 2}, + { "am486dx2", 80000000, 2}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_Cx486S1[] = { - {"cx486s", 25000000, 1.0}, - {"cx486s", 33333333, 1.0}, - {"cx486s", 40000000, 1.0}, - {"cx486dx", 33333333, 1.0}, - {"cx486dx", 40000000, 1.0}, - {"cx486dx2", 50000000, 2.0}, - {"cx486dx2", 66666666, 2.0}, - {"cx486dx2", 80000000, 2.0}, - {NULL, 0, 0} + {"cx486s", 25000000, 1.0}, + { "cx486s", 33333333, 1.0}, + { "cx486s", 40000000, 1.0}, + { "cx486dx", 33333333, 1.0}, + { "cx486dx", 40000000, 1.0}, + { "cx486dx2", 50000000, 2.0}, + { "cx486dx2", 66666666, 2.0}, + { "cx486dx2", 80000000, 2.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_i486[] = { - {"i486sx", 16000000, 1.0}, - {"i486sx", 20000000, 1.0}, - {"i486sx", 25000000, 1.0}, - {"i486sx", 33333333, 1.0}, - {"i486sx2", 50000000, 2.0}, - {"i486sx2", 66666666, 2.0}, - {"i486dx", 25000000, 1.0}, - {"i486dx", 33333333, 1.0}, - {"i486dx", 50000000, 1.0}, - {"i486dx2", 40000000, 2.0}, - {"i486dx2", 50000000, 2.0}, - {"i486dx2", 66666666, 2.0}, - {"idx4", 75000000, 3.0}, - {"idx4", 100000000, 3.0}, - {"idx4_od", 75000000, 3.0}, - {"idx4_od", 100000000, 3.0}, - {"pentium_p24t", 62500000, 2.5}, - {"pentium_p24t", 83333333, 2.5}, - {NULL, 0, 0} + {"i486sx", 16000000, 1.0}, + { "i486sx", 20000000, 1.0}, + { "i486sx", 25000000, 1.0}, + { "i486sx", 33333333, 1.0}, + { "i486sx2", 50000000, 2.0}, + { "i486sx2", 66666666, 2.0}, + { "i486dx", 25000000, 1.0}, + { "i486dx", 33333333, 1.0}, + { "i486dx", 50000000, 1.0}, + { "i486dx2", 40000000, 2.0}, + { "i486dx2", 50000000, 2.0}, + { "i486dx2", 66666666, 2.0}, + { "idx4", 75000000, 3.0}, + { "idx4", 100000000, 3.0}, + { "idx4_od", 75000000, 3.0}, + { "idx4_od", 100000000, 3.0}, + { "pentium_p24t", 62500000, 2.5}, + { "pentium_p24t", 83333333, 2.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_i486_PC330[] = { - {"i486dx2", 50000000, 2.0}, - {"i486dx2", 66666666, 2.0}, - {"idx4", 75000000, 3.0}, - {"idx4", 100000000, 3.0}, - {"pentium_p24t", 62500000, 2.5}, - {"pentium_p24t", 83333333, 2.5}, - {NULL, 0, 0} + {"i486dx2", 50000000, 2.0}, + { "i486dx2", 66666666, 2.0}, + { "idx4", 75000000, 3.0}, + { "idx4", 100000000, 3.0}, + { "pentium_p24t", 62500000, 2.5}, + { "pentium_p24t", 83333333, 2.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Am486[] = { - {"am486sx", 33333333, 1.0}, - {"am486sx", 40000000, 1.0}, - {"am486sx2", 50000000, 2.0}, - {"am486sx2", 66666666, 2.0}, - {"am486dx", 33333333, 1.0}, - {"am486dx", 40000000, 1.0}, - {"am486dx2", 50000000, 2.0}, - {"am486dx2", 66666666, 2.0}, - {"am486dx2", 80000000, 2.0}, - {"am486dx4", 75000000, 3.0}, - {"am486dx4", 90000000, 3.0}, - {"am486dx4", 100000000, 3.0}, - {"am486dx4", 120000000, 3.0}, - {"am5x86", 133333333, 4.0}, - {"am5x86", 150000000, 3.0}, - {"am5x86", 160000000, 4.0}, - {NULL, 0, 0} + {"am486sx", 33333333, 1.0}, + { "am486sx", 40000000, 1.0}, + { "am486sx2", 50000000, 2.0}, + { "am486sx2", 66666666, 2.0}, + { "am486dx", 33333333, 1.0}, + { "am486dx", 40000000, 1.0}, + { "am486dx2", 50000000, 2.0}, + { "am486dx2", 66666666, 2.0}, + { "am486dx2", 80000000, 2.0}, + { "am486dx4", 75000000, 3.0}, + { "am486dx4", 90000000, 3.0}, + { "am486dx4", 100000000, 3.0}, + { "am486dx4", 120000000, 3.0}, + { "am5x86", 133333333, 4.0}, + { "am5x86", 150000000, 3.0}, + { "am5x86", 160000000, 4.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Cx486[] = { - {"cx486s", 25000000, 1.0}, - {"cx486s", 33333333, 1.0}, - {"cx486s", 40000000, 1.0}, - {"cx486dx", 33333333, 1.0}, - {"cx486dx", 40000000, 1.0}, - {"cx486dx2", 50000000, 2.0}, - {"cx486dx2", 66666666, 2.0}, - {"cx486dx2", 80000000, 2.0}, - {"cx486dx4", 75000000, 3.0}, - {"cx486dx4", 100000000, 3.0}, - {"cx5x86", 80000000, 2.0}, - {"cx5x86", 100000000, 3.0}, - {"cx5x86", 120000000, 3.0}, - {"cx5x86", 133333333, 4.0}, - {NULL, 0, 0} + {"cx486s", 25000000, 1.0}, + { "cx486s", 33333333, 1.0}, + { "cx486s", 40000000, 1.0}, + { "cx486dx", 33333333, 1.0}, + { "cx486dx", 40000000, 1.0}, + { "cx486dx2", 50000000, 2.0}, + { "cx486dx2", 66666666, 2.0}, + { "cx486dx2", 80000000, 2.0}, + { "cx486dx4", 75000000, 3.0}, + { "cx486dx4", 100000000, 3.0}, + { "cx5x86", 80000000, 2.0}, + { "cx5x86", 100000000, 3.0}, + { "cx5x86", 120000000, 3.0}, + { "cx5x86", 133333333, 4.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_STPCDX[] = { - {"stpc_dx", 66666666, 1.0}, - {"stpc_dx", 75000000, 1.0}, - {NULL, 0, 0} + {"stpc_dx", 66666666, 1.0}, + { "stpc_dx", 75000000, 1.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_STPCDX2[] = { {"stpc_dx2", 133333333, 2.0}, - {NULL, 0, 0} + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_6x863V[] = { - {"cx6x86", 80000000, 2.0}, - {"cx6x86", 100000000, 2.0}, - {"cx6x86", 110000000, 2.0}, - {"cx6x86", 120000000, 2.0}, - {"cx6x86", 133333333, 2.0}, - {"cx6x86", 150000000, 2.0}, - {NULL, 0, 0} + {"cx6x86", 80000000, 2.0}, + { "cx6x86", 100000000, 2.0}, + { "cx6x86", 110000000, 2.0}, + { "cx6x86", 120000000, 2.0}, + { "cx6x86", 133333333, 2.0}, + { "cx6x86", 150000000, 2.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_6x86[] = { - {"cx6x86", 80000000, 2.0}, - {"cx6x86", 100000000, 2.0}, - {"cx6x86", 110000000, 2.0}, - {"cx6x86", 120000000, 2.0}, - {"cx6x86", 133333333, 2.0}, - {"cx6x86", 150000000, 2.0}, - {"cx6x86l", 110000000, 2.0}, - {"cx6x86l", 120000000, 2.0}, - {"cx6x86l", 133333333, 2.0}, - {"cx6x86l", 150000000, 2.0}, - {"cx6x86mx", 133333333, 2.0}, - {"cx6x86mx", 166666666, 2.5}, - {"cx6x86mx", 187500000, 2.5}, - {"cx6x86mx", 208333333, 2.5}, - {"mii", 233333333, 3.5}, - {"mii", 250000000, 3.0}, - {NULL, 0, 0} + {"cx6x86", 80000000, 2.0}, + { "cx6x86", 100000000, 2.0}, + { "cx6x86", 110000000, 2.0}, + { "cx6x86", 120000000, 2.0}, + { "cx6x86", 133333333, 2.0}, + { "cx6x86", 150000000, 2.0}, + { "cx6x86l", 110000000, 2.0}, + { "cx6x86l", 120000000, 2.0}, + { "cx6x86l", 133333333, 2.0}, + { "cx6x86l", 150000000, 2.0}, + { "cx6x86mx", 133333333, 2.0}, + { "cx6x86mx", 166666666, 2.5}, + { "cx6x86mx", 187500000, 2.5}, + { "cx6x86mx", 208333333, 2.5}, + { "mii", 233333333, 3.5}, + { "mii", 250000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_6x86SS7[] = { - {"cx6x86", 80000000, 2.0}, - {"cx6x86", 100000000, 2.0}, - {"cx6x86", 110000000, 2.0}, - {"cx6x86", 120000000, 2.0}, - {"cx6x86", 133333333, 2.0}, - {"cx6x86", 150000000, 2.0}, - {"cx6x86l", 110000000, 2.0}, - {"cx6x86l", 120000000, 2.0}, - {"cx6x86l", 133333333, 2.0}, - {"cx6x86l", 150000000, 2.0}, - {"cx6x86mx", 133333333, 2.0}, - {"cx6x86mx", 166666666, 2.5}, - {"cx6x86mx", 187500000, 2.5}, - {"cx6x86mx", 208333333, 2.5}, - {"mii", 233333333, 3.5}, - {"mii", 250000000, 3.0}, - {"mii", 250000000, 2.5}, - {"mii", 285000000, 3.0}, - {"mii", 300000000, 3.0}, - {NULL, 0, 0} + {"cx6x86", 80000000, 2.0}, + { "cx6x86", 100000000, 2.0}, + { "cx6x86", 110000000, 2.0}, + { "cx6x86", 120000000, 2.0}, + { "cx6x86", 133333333, 2.0}, + { "cx6x86", 150000000, 2.0}, + { "cx6x86l", 110000000, 2.0}, + { "cx6x86l", 120000000, 2.0}, + { "cx6x86l", 133333333, 2.0}, + { "cx6x86l", 150000000, 2.0}, + { "cx6x86mx", 133333333, 2.0}, + { "cx6x86mx", 166666666, 2.5}, + { "cx6x86mx", 187500000, 2.5}, + { "cx6x86mx", 208333333, 2.5}, + { "mii", 233333333, 3.5}, + { "mii", 250000000, 3.0}, + { "mii", 250000000, 2.5}, + { "mii", 285000000, 3.0}, + { "mii", 300000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_WinChip[] = { - {"winchip", 75000000, 1.5}, - {"winchip", 90000000, 1.5}, - {"winchip", 100000000, 1.5}, - {"winchip", 120000000, 2.0}, - {"winchip", 133333333, 2.0}, - {"winchip", 150000000, 2.5}, - {"winchip", 166666666, 2.5}, - {"winchip", 180000000, 3.0}, - {"winchip", 200000000, 3.0}, - {"winchip", 225000000, 3.0}, - {"winchip", 240000000, 4.0}, - {"winchip2", 200000000, 3.0}, - {"winchip2", 225000000, 3.0}, - {"winchip2", 240000000, 4.0}, - {"winchip2", 250000000, 3.0}, - {"winchip2a", 200000000, 3.0}, - {"winchip2a", 233333333, 3.5}, - {NULL, 0, 0} + {"winchip", 75000000, 1.5}, + { "winchip", 90000000, 1.5}, + { "winchip", 100000000, 1.5}, + { "winchip", 120000000, 2.0}, + { "winchip", 133333333, 2.0}, + { "winchip", 150000000, 2.5}, + { "winchip", 166666666, 2.5}, + { "winchip", 180000000, 3.0}, + { "winchip", 200000000, 3.0}, + { "winchip", 225000000, 3.0}, + { "winchip", 240000000, 4.0}, + { "winchip2", 200000000, 3.0}, + { "winchip2", 225000000, 3.0}, + { "winchip2", 240000000, 4.0}, + { "winchip2", 250000000, 3.0}, + { "winchip2a", 200000000, 3.0}, + { "winchip2a", 233333333, 3.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_WinChip_SS7[] = { - {"winchip", 75000000, 1.5}, - {"winchip", 90000000, 1.5}, - {"winchip", 100000000, 1.5}, - {"winchip", 120000000, 2.0}, - {"winchip", 133333333, 2.0}, - {"winchip", 150000000, 2.5}, - {"winchip", 166666666, 2.5}, - {"winchip", 180000000, 3.0}, - {"winchip", 200000000, 3.0}, - {"winchip", 225000000, 3.0}, - {"winchip", 240000000, 4.0}, - {"winchip2", 200000000, 3.0}, - {"winchip2", 225000000, 3.0}, - {"winchip2", 240000000, 4.0}, - {"winchip2", 250000000, 3.0}, - {"winchip2a", 200000000, 3.0}, - {"winchip2a", 233333333, 3.5}, - {"winchip2a", 233333333, 7.0}, - {"winchip2a", 250000000, 2.5}, - {NULL, 0, 0} + {"winchip", 75000000, 1.5}, + { "winchip", 90000000, 1.5}, + { "winchip", 100000000, 1.5}, + { "winchip", 120000000, 2.0}, + { "winchip", 133333333, 2.0}, + { "winchip", 150000000, 2.5}, + { "winchip", 166666666, 2.5}, + { "winchip", 180000000, 3.0}, + { "winchip", 200000000, 3.0}, + { "winchip", 225000000, 3.0}, + { "winchip", 240000000, 4.0}, + { "winchip2", 200000000, 3.0}, + { "winchip2", 225000000, 3.0}, + { "winchip2", 240000000, 4.0}, + { "winchip2", 250000000, 3.0}, + { "winchip2a", 200000000, 3.0}, + { "winchip2a", 233333333, 3.5}, + { "winchip2a", 233333333, 7.0}, + { "winchip2a", 250000000, 2.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Pentium5V[] = { - {"pentium_p5", 60000000, 1}, - {"pentium_p5", 66666666, 1}, - {"pentium_p54c_od5v", 120000000, 2}, - {"pentium_p54c_od5v", 133333333, 2}, - {NULL, 0, 0} + {"pentium_p5", 60000000, 1}, + { "pentium_p5", 66666666, 1}, + { "pentium_p54c_od5v", 120000000, 2}, + { "pentium_p54c_od5v", 133333333, 2}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_PentiumS5[] = { - {"pentium_p54c", 75000000, 1.5}, - {"pentium_p55c_od", 75000000, 1.5}, - {"pentium_p54c", 90000000, 1.5}, - {"pentium_p54c", 100000000, 2.0}, - {"pentium_p54c", 100000000, 1.5}, - {"pentium_p54c", 120000000, 2.0}, - {"pentium_p54c", 133333333, 2.0}, - {"pentium_p54c_od3v", 125000000, 3.0}, - {"pentium_p54c_od3v", 150000000, 2.5}, - {"pentium_p54c_od3v", 166666666, 2.5}, - {"pentium_p55c_od", 125000000, 2.5}, - {"pentium_p55c_od", 150000000, 2.5}, - {"pentium_p55c_od", 166000000, 2.5}, - {"pentium_p55c_od", 180000000, 3.0}, - {"pentium_p55c_od", 200000000, 3.0}, - {NULL, 0, 0} + {"pentium_p54c", 75000000, 1.5}, + { "pentium_p55c_od", 75000000, 1.5}, + { "pentium_p54c", 90000000, 1.5}, + { "pentium_p54c", 100000000, 2.0}, + { "pentium_p54c", 100000000, 1.5}, + { "pentium_p54c", 120000000, 2.0}, + { "pentium_p54c", 133333333, 2.0}, + { "pentium_p54c_od3v", 125000000, 3.0}, + { "pentium_p54c_od3v", 150000000, 2.5}, + { "pentium_p54c_od3v", 166666666, 2.5}, + { "pentium_p55c_od", 125000000, 2.5}, + { "pentium_p55c_od", 150000000, 2.5}, + { "pentium_p55c_od", 166000000, 2.5}, + { "pentium_p55c_od", 180000000, 3.0}, + { "pentium_p55c_od", 200000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Pentium3V[] = { - {"pentium_p54c", 75000000, 1.5}, - {"pentium_p55c_od", 75000000, 1.5}, - {"pentium_p54c", 90000000, 1.5}, - {"pentium_p54c", 100000000, 2.0}, - {"pentium_p54c", 100000000, 1.5}, - {"pentium_p54c", 120000000, 2.0}, - {"pentium_p54c", 133333333, 2.0}, - {"pentium_p54c", 150000000, 2.5}, - {"pentium_p54c", 166666666, 2.5}, - {"pentium_p54c", 200000000, 3.0}, - {"pentium_p54c_od3v", 125000000, 2.5}, - {"pentium_p54c_od3v", 150000000, 2.5}, - {"pentium_p54c_od3v", 166666666, 2.5}, - {"pentium_p55c_od", 125000000, 2.5}, - {"pentium_p55c_od", 150000000, 2.5}, - {"pentium_p55c_od", 166000000, 2.5}, - {"pentium_p55c_od", 180000000, 3.0}, - {"pentium_p55c_od", 200000000, 3.0}, - {NULL, 0, 0} + {"pentium_p54c", 75000000, 1.5}, + { "pentium_p55c_od", 75000000, 1.5}, + { "pentium_p54c", 90000000, 1.5}, + { "pentium_p54c", 100000000, 2.0}, + { "pentium_p54c", 100000000, 1.5}, + { "pentium_p54c", 120000000, 2.0}, + { "pentium_p54c", 133333333, 2.0}, + { "pentium_p54c", 150000000, 2.5}, + { "pentium_p54c", 166666666, 2.5}, + { "pentium_p54c", 200000000, 3.0}, + { "pentium_p54c_od3v", 125000000, 2.5}, + { "pentium_p54c_od3v", 150000000, 2.5}, + { "pentium_p54c_od3v", 166666666, 2.5}, + { "pentium_p55c_od", 125000000, 2.5}, + { "pentium_p55c_od", 150000000, 2.5}, + { "pentium_p55c_od", 166000000, 2.5}, + { "pentium_p55c_od", 180000000, 3.0}, + { "pentium_p55c_od", 200000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Pentium[] = { - {"pentium_p54c", 75000000, 1.5}, - {"pentium_p55c_od", 75000000, 1.5}, - {"pentium_p54c", 90000000, 1.5}, - {"pentium_p54c", 100000000, 2.0}, - {"pentium_p54c", 100000000, 1.5}, - {"pentium_p54c", 120000000, 2.0}, - {"pentium_p54c", 133333333, 2.0}, - {"pentium_p54c", 150000000, 2.5}, - {"pentium_p54c", 166666666, 2.5}, - {"pentium_p54c", 200000000, 3.0}, - {"pentium_p55c", 166666666, 2.5}, - {"pentium_p55c", 200000000, 3.0}, - {"pentium_p55c", 233333333, 3.5}, - {"pentium_tillamook", 120000000, 2.0}, - {"pentium_tillamook", 133333333, 2.0}, - {"pentium_tillamook", 150000000, 2.5}, - {"pentium_tillamook", 166666666, 2.5}, - {"pentium_tillamook", 200000000, 3.0}, - {"pentium_tillamook", 233333333, 3.5}, - {"pentium_tillamook", 266666666, 4.0}, - {"pentium_tillamook", 300000000, 4.5}, - {"pentium_p54c_od3v", 125000000, 2.5}, - {"pentium_p54c_od3v", 150000000, 2.5}, - {"pentium_p54c_od3v", 166666666, 2.5}, - {"pentium_p55c_od", 125000000, 2.5}, - {"pentium_p55c_od", 150000000, 2.5}, - {"pentium_p55c_od", 166000000, 2.5}, - {"pentium_p55c_od", 180000000, 3.0}, - {"pentium_p55c_od", 200000000, 3.0}, - {NULL, 0, 0} + {"pentium_p54c", 75000000, 1.5}, + { "pentium_p55c_od", 75000000, 1.5}, + { "pentium_p54c", 90000000, 1.5}, + { "pentium_p54c", 100000000, 2.0}, + { "pentium_p54c", 100000000, 1.5}, + { "pentium_p54c", 120000000, 2.0}, + { "pentium_p54c", 133333333, 2.0}, + { "pentium_p54c", 150000000, 2.5}, + { "pentium_p54c", 166666666, 2.5}, + { "pentium_p54c", 200000000, 3.0}, + { "pentium_p55c", 166666666, 2.5}, + { "pentium_p55c", 200000000, 3.0}, + { "pentium_p55c", 233333333, 3.5}, + { "pentium_tillamook", 120000000, 2.0}, + { "pentium_tillamook", 133333333, 2.0}, + { "pentium_tillamook", 150000000, 2.5}, + { "pentium_tillamook", 166666666, 2.5}, + { "pentium_tillamook", 200000000, 3.0}, + { "pentium_tillamook", 233333333, 3.5}, + { "pentium_tillamook", 266666666, 4.0}, + { "pentium_tillamook", 300000000, 4.5}, + { "pentium_p54c_od3v", 125000000, 2.5}, + { "pentium_p54c_od3v", 150000000, 2.5}, + { "pentium_p54c_od3v", 166666666, 2.5}, + { "pentium_p55c_od", 125000000, 2.5}, + { "pentium_p55c_od", 150000000, 2.5}, + { "pentium_p55c_od", 166000000, 2.5}, + { "pentium_p55c_od", 180000000, 3.0}, + { "pentium_p55c_od", 200000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_K5[] = { - {"k5_5k86", 75000000, 1.5}, - {"k5_ssa5", 75000000, 1.5}, - {"k5_5k86", 90000000, 1.5}, - {"k5_ssa5", 90000000, 1.5}, - {"k5_5k86", 100000000, 1.5}, - {"k5_ssa5", 100000000, 1.5}, - {"k5_5k86", 120000000, 2.0}, - {"k5_5k86", 133333333, 2.0}, - {"k5_5k86", 150000000, 2.5}, - {"k5_5k86", 166666666, 2.5}, - {"k5_5k86", 200000000, 3.0}, - {NULL, 0, 0} + {"k5_5k86", 75000000, 1.5}, + { "k5_ssa5", 75000000, 1.5}, + { "k5_5k86", 90000000, 1.5}, + { "k5_ssa5", 90000000, 1.5}, + { "k5_5k86", 100000000, 1.5}, + { "k5_ssa5", 100000000, 1.5}, + { "k5_5k86", 120000000, 2.0}, + { "k5_5k86", 133333333, 2.0}, + { "k5_5k86", 150000000, 2.5}, + { "k5_5k86", 166666666, 2.5}, + { "k5_5k86", 200000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_K56[] = { - {"k6_m6", 66666666, 1.0}, - {"k6_m6", 100000000, 1.5}, - {"k6_m6", 133333333, 2.0}, - {"k6_m6", 166666666, 2.5}, - {"k6_m6", 200000000, 3.0}, - {"k6_m6", 233333333, 3.5}, - {"k6_m7", 100000000, 1.5}, - {"k6_m7", 133333333, 2.0}, - {"k6_m7", 166666666, 2.5}, - {"k6_m7", 200000000, 3.0}, - {"k6_m7", 233333333, 3.5}, - {"k6_m7", 266666666, 4.0}, - {"k6_m7", 300000000, 4.5}, - {"k6_2", 100000000, 1.5}, - {"k6_2", 133333333, 2.0}, - {"k6_2", 166666666, 2.5}, - {"k6_2", 200000000, 3.0}, - {"k6_2", 233333333, 3.5}, - {"k6_2", 266666666, 4.0}, - {"k6_2", 300000000, 4.5}, - {"k6_2", 366666666, 5.5}, - {NULL, 0, 0} + {"k6_m6", 66666666, 1.0}, + { "k6_m6", 100000000, 1.5}, + { "k6_m6", 133333333, 2.0}, + { "k6_m6", 166666666, 2.5}, + { "k6_m6", 200000000, 3.0}, + { "k6_m6", 233333333, 3.5}, + { "k6_m7", 100000000, 1.5}, + { "k6_m7", 133333333, 2.0}, + { "k6_m7", 166666666, 2.5}, + { "k6_m7", 200000000, 3.0}, + { "k6_m7", 233333333, 3.5}, + { "k6_m7", 266666666, 4.0}, + { "k6_m7", 300000000, 4.5}, + { "k6_2", 100000000, 1.5}, + { "k6_2", 133333333, 2.0}, + { "k6_2", 166666666, 2.5}, + { "k6_2", 200000000, 3.0}, + { "k6_2", 233333333, 3.5}, + { "k6_2", 266666666, 4.0}, + { "k6_2", 300000000, 4.5}, + { "k6_2", 366666666, 5.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_K56_SS7[] = { - {"k6_m6", 66666666, 1.0}, - {"k6_m6", 100000000, 1.5}, - {"k6_m6", 133333333, 2.0}, - {"k6_m6", 166666666, 2.5}, - {"k6_m6", 200000000, 3.0}, - {"k6_m6", 233333333, 3.5}, - {"k6_m7", 100000000, 1.5}, - {"k6_m7", 133333333, 2.0}, - {"k6_m7", 166666666, 2.5}, - {"k6_m7", 200000000, 3.0}, - {"k6_m7", 233333333, 3.5}, - {"k6_m7", 266666666, 4.0}, - {"k6_m7", 300000000, 4.5}, - {"k6_2", 100000000, 1.5}, - {"k6_2", 133333333, 2.0}, - {"k6_2", 166666666, 2.5}, - {"k6_2", 200000000, 3.0}, - {"k6_2", 233333333, 3.5}, - {"k6_2", 266666666, 4.0}, - {"k6_2", 300000000, 3.0}, - {"k6_2", 332500000, 3.5}, - {"k6_2", 350000000, 3.5}, - {"k6_2", 366666666, 5.5}, - {"k6_2", 380000000, 4.0}, - {"k6_2", 400000000, 4.0}, - {"k6_2", 450000000, 4.5}, - {"k6_2", 475000000, 5.0}, - {"k6_2", 500000000, 5.0}, - {"k6_2", 533333333, 5.5}, - {"k6_2", 550000000, 5.5}, - {"k6_2p", 100000000, 1.5}, - {"k6_2p", 133333333, 2.0}, - {"k6_2p", 166666666, 2.5}, - {"k6_2p", 200000000, 3.0}, - {"k6_2p", 233333333, 3.5}, - {"k6_2p", 266666666, 4.0}, - {"k6_2p", 300000000, 3.0}, - {"k6_2p", 332500000, 3.5}, - {"k6_2p", 350000000, 3.5}, - {"k6_2p", 366666666, 5.5}, - {"k6_2p", 380000000, 4.0}, - {"k6_2p", 400000000, 4.0}, - {"k6_2p", 450000000, 4.5}, - {"k6_2p", 475000000, 5.0}, - {"k6_2p", 500000000, 5.0}, - {"k6_2p", 533333333, 5.5}, - {"k6_2p", 550000000, 5.5}, - {"k6_3", 100000000, 1.5}, - {"k6_3", 133333333, 2.0}, - {"k6_3", 166666666, 2.5}, - {"k6_3", 200000000, 3.0}, - {"k6_3", 233333333, 3.5}, - {"k6_3", 266666666, 4.0}, - {"k6_3", 300000000, 3.0}, - {"k6_3", 332500000, 3.5}, - {"k6_3", 350000000, 3.5}, - {"k6_3", 366666666, 5.5}, - {"k6_3", 380000000, 4.0}, - {"k6_3", 400000000, 4.0}, - {"k6_3", 450000000, 4.5}, - {"k6_3p", 75000000, 1.5}, - {"k6_3p", 100000000, 1.5}, - {"k6_3p", 133333333, 2.0}, - {"k6_3p", 166666666, 2.5}, - {"k6_3p", 200000000, 3.0}, - {"k6_3p", 233333333, 3.5}, - {"k6_3p", 266666666, 4.0}, - {"k6_3p", 300000000, 3.0}, - {"k6_3p", 332500000, 3.5}, - {"k6_3p", 350000000, 3.5}, - {"k6_3p", 366666666, 5.5}, - {"k6_3p", 380000000, 4.0}, - {"k6_3p", 400000000, 4.0}, - {"k6_3p", 450000000, 4.5}, - {"k6_3p", 475000000, 5.0}, - {"k6_3p", 500000000, 5.0}, - {NULL, 0, 0} + {"k6_m6", 66666666, 1.0}, + { "k6_m6", 100000000, 1.5}, + { "k6_m6", 133333333, 2.0}, + { "k6_m6", 166666666, 2.5}, + { "k6_m6", 200000000, 3.0}, + { "k6_m6", 233333333, 3.5}, + { "k6_m7", 100000000, 1.5}, + { "k6_m7", 133333333, 2.0}, + { "k6_m7", 166666666, 2.5}, + { "k6_m7", 200000000, 3.0}, + { "k6_m7", 233333333, 3.5}, + { "k6_m7", 266666666, 4.0}, + { "k6_m7", 300000000, 4.5}, + { "k6_2", 100000000, 1.5}, + { "k6_2", 133333333, 2.0}, + { "k6_2", 166666666, 2.5}, + { "k6_2", 200000000, 3.0}, + { "k6_2", 233333333, 3.5}, + { "k6_2", 266666666, 4.0}, + { "k6_2", 300000000, 3.0}, + { "k6_2", 332500000, 3.5}, + { "k6_2", 350000000, 3.5}, + { "k6_2", 366666666, 5.5}, + { "k6_2", 380000000, 4.0}, + { "k6_2", 400000000, 4.0}, + { "k6_2", 450000000, 4.5}, + { "k6_2", 475000000, 5.0}, + { "k6_2", 500000000, 5.0}, + { "k6_2", 533333333, 5.5}, + { "k6_2", 550000000, 5.5}, + { "k6_2p", 100000000, 1.5}, + { "k6_2p", 133333333, 2.0}, + { "k6_2p", 166666666, 2.5}, + { "k6_2p", 200000000, 3.0}, + { "k6_2p", 233333333, 3.5}, + { "k6_2p", 266666666, 4.0}, + { "k6_2p", 300000000, 3.0}, + { "k6_2p", 332500000, 3.5}, + { "k6_2p", 350000000, 3.5}, + { "k6_2p", 366666666, 5.5}, + { "k6_2p", 380000000, 4.0}, + { "k6_2p", 400000000, 4.0}, + { "k6_2p", 450000000, 4.5}, + { "k6_2p", 475000000, 5.0}, + { "k6_2p", 500000000, 5.0}, + { "k6_2p", 533333333, 5.5}, + { "k6_2p", 550000000, 5.5}, + { "k6_3", 100000000, 1.5}, + { "k6_3", 133333333, 2.0}, + { "k6_3", 166666666, 2.5}, + { "k6_3", 200000000, 3.0}, + { "k6_3", 233333333, 3.5}, + { "k6_3", 266666666, 4.0}, + { "k6_3", 300000000, 3.0}, + { "k6_3", 332500000, 3.5}, + { "k6_3", 350000000, 3.5}, + { "k6_3", 366666666, 5.5}, + { "k6_3", 380000000, 4.0}, + { "k6_3", 400000000, 4.0}, + { "k6_3", 450000000, 4.5}, + { "k6_3p", 75000000, 1.5}, + { "k6_3p", 100000000, 1.5}, + { "k6_3p", 133333333, 2.0}, + { "k6_3p", 166666666, 2.5}, + { "k6_3p", 200000000, 3.0}, + { "k6_3p", 233333333, 3.5}, + { "k6_3p", 266666666, 4.0}, + { "k6_3p", 300000000, 3.0}, + { "k6_3p", 332500000, 3.5}, + { "k6_3p", 350000000, 3.5}, + { "k6_3p", 366666666, 5.5}, + { "k6_3p", 380000000, 4.0}, + { "k6_3p", 400000000, 4.0}, + { "k6_3p", 450000000, 4.5}, + { "k6_3p", 475000000, 5.0}, + { "k6_3p", 500000000, 5.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_PentiumPro[] = { - {"pentiumpro", 50000000, 1.0}, - {"pentiumpro", 60000000, 1.0}, - {"pentiumpro", 66666666, 1.0}, - {"pentiumpro", 75000000, 1.5}, - {"pentiumpro", 150000000, 2.5}, - {"pentiumpro", 166666666, 2.5}, - {"pentiumpro", 180000000, 3.0}, - {"pentiumpro", 200000000, 3.0}, - {"pentium2_od", 50000000, 1.0}, - {"pentium2_od", 60000000, 1.0}, - {"pentium2_od", 66666666, 1.0}, - {"pentium2_od", 75000000, 1.5}, - {"pentium2_od", 210000000, 3.5}, - {"pentium2_od", 233333333, 3.5}, - {"pentium2_od", 240000000, 4.0}, - {"pentium2_od", 266666666, 4.0}, - {"pentium2_od", 270000000, 4.5}, - {"pentium2_od", 300000000, 4.5}, - {"pentium2_od", 300000000, 5.0}, - {"pentium2_od", 333333333, 5.0}, - {NULL, 0, 0} + {"pentiumpro", 50000000, 1.0}, + { "pentiumpro", 60000000, 1.0}, + { "pentiumpro", 66666666, 1.0}, + { "pentiumpro", 75000000, 1.5}, + { "pentiumpro", 150000000, 2.5}, + { "pentiumpro", 166666666, 2.5}, + { "pentiumpro", 180000000, 3.0}, + { "pentiumpro", 200000000, 3.0}, + { "pentium2_od", 50000000, 1.0}, + { "pentium2_od", 60000000, 1.0}, + { "pentium2_od", 66666666, 1.0}, + { "pentium2_od", 75000000, 1.5}, + { "pentium2_od", 210000000, 3.5}, + { "pentium2_od", 233333333, 3.5}, + { "pentium2_od", 240000000, 4.0}, + { "pentium2_od", 266666666, 4.0}, + { "pentium2_od", 270000000, 4.5}, + { "pentium2_od", 300000000, 4.5}, + { "pentium2_od", 300000000, 5.0}, + { "pentium2_od", 333333333, 5.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_PentiumII66[] = { - {"pentium2_klamath", 50000000, 1.0}, - {"pentium2_klamath", 60000000, 1.0}, - {"pentium2_klamath", 66666666, 1.0}, - {"pentium2_klamath", 75000000, 1.5}, - {"pentium2_klamath", 233333333, 3.5}, - {"pentium2_klamath", 266666666, 4.0}, - {"pentium2_klamath", 300000000, 4.5}, - {"pentium2_deschutes", 50000000, 1.0}, - {"pentium2_deschutes", 60000000, 1.0}, - {"pentium2_deschutes", 66666666, 1.0}, - {"pentium2_deschutes", 75000000, 1.5}, - {"pentium2_deschutes", 266666666, 4.0}, - {"pentium2_deschutes", 300000000, 4.5}, - {"pentium2_deschutes", 333333333, 5.0}, - {NULL, 0, 0} - + {"pentium2_klamath", 50000000, 1.0}, + { "pentium2_klamath", 60000000, 1.0}, + { "pentium2_klamath", 66666666, 1.0}, + { "pentium2_klamath", 75000000, 1.5}, + { "pentium2_klamath", 233333333, 3.5}, + { "pentium2_klamath", 266666666, 4.0}, + { "pentium2_klamath", 300000000, 4.5}, + { "pentium2_deschutes", 50000000, 1.0}, + { "pentium2_deschutes", 60000000, 1.0}, + { "pentium2_deschutes", 66666666, 1.0}, + { "pentium2_deschutes", 75000000, 1.5}, + { "pentium2_deschutes", 266666666, 4.0}, + { "pentium2_deschutes", 300000000, 4.5}, + { "pentium2_deschutes", 333333333, 5.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_PentiumII[] = { - {"pentium2_klamath", 50000000, 1.0}, - {"pentium2_klamath", 60000000, 1.0}, - {"pentium2_klamath", 66666666, 1.0}, - {"pentium2_klamath", 75000000, 1.5}, - {"pentium2_klamath", 233333333, 3.5}, - {"pentium2_klamath", 266666666, 4.0}, - {"pentium2_klamath", 300000000, 4.5}, - {"pentium2_deschutes", 50000000, 1.0}, - {"pentium2_deschutes", 60000000, 1.0}, - {"pentium2_deschutes", 66666666, 1.0}, - {"pentium2_deschutes", 75000000, 1.5}, - {"pentium2_deschutes", 266666666, 4.0}, - {"pentium2_deschutes", 300000000, 4.5}, - {"pentium2_deschutes", 333333333, 5.0}, - {"pentium2_deschutes", 350000000, 3.5}, - {"pentium2_deschutes", 400000000, 4.0}, - {"pentium2_deschutes", 450000000, 4.5}, - {NULL, 0, 0} + {"pentium2_klamath", 50000000, 1.0}, + { "pentium2_klamath", 60000000, 1.0}, + { "pentium2_klamath", 66666666, 1.0}, + { "pentium2_klamath", 75000000, 1.5}, + { "pentium2_klamath", 233333333, 3.5}, + { "pentium2_klamath", 266666666, 4.0}, + { "pentium2_klamath", 300000000, 4.5}, + { "pentium2_deschutes", 50000000, 1.0}, + { "pentium2_deschutes", 60000000, 1.0}, + { "pentium2_deschutes", 66666666, 1.0}, + { "pentium2_deschutes", 75000000, 1.5}, + { "pentium2_deschutes", 266666666, 4.0}, + { "pentium2_deschutes", 300000000, 4.5}, + { "pentium2_deschutes", 333333333, 5.0}, + { "pentium2_deschutes", 350000000, 3.5}, + { "pentium2_deschutes", 400000000, 4.0}, + { "pentium2_deschutes", 450000000, 4.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Xeon[] = { - {"pentium2_xeon", 75000000, 1.5}, - {"pentium2_xeon", 100000000, 1.5}, - {"pentium2_xeon", 133333333, 2.0}, - {"pentium2_xeon", 166666666, 2.5}, - {"pentium2_xeon", 400000000, 4.0}, - {"pentium2_xeon", 450000000, 4.5}, - {NULL, 0, 0} + {"pentium2_xeon", 75000000, 1.5}, + { "pentium2_xeon", 100000000, 1.5}, + { "pentium2_xeon", 133333333, 2.0}, + { "pentium2_xeon", 166666666, 2.5}, + { "pentium2_xeon", 400000000, 4.0}, + { "pentium2_xeon", 450000000, 4.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Celeron[] = { - {"celeron_mendocino", 66666666, 1.0}, - {"celeron_mendocino", 100000000, 1.5}, - {"celeron_mendocino", 133333333, 2.0}, - {"celeron_mendocino", 166666666, 2.5}, - {"celeron_mendocino", 300000000, 4.5}, - {"celeron_mendocino", 333333333, 5.0}, - {"celeron_mendocino", 366666666, 5.5}, - {"celeron_mendocino", 400000000, 6.0}, - {"celeron_mendocino", 433333333, 6.5}, - {"celeron_mendocino", 466666666, 7.0}, - {"celeron_mendocino", 500000000, 7.5}, - {"celeron_mendocino", 533333333, 8.0}, - {NULL, 0, 0} + {"celeron_mendocino", 66666666, 1.0}, + { "celeron_mendocino", 100000000, 1.5}, + { "celeron_mendocino", 133333333, 2.0}, + { "celeron_mendocino", 166666666, 2.5}, + { "celeron_mendocino", 300000000, 4.5}, + { "celeron_mendocino", 333333333, 5.0}, + { "celeron_mendocino", 366666666, 5.5}, + { "celeron_mendocino", 400000000, 6.0}, + { "celeron_mendocino", 433333333, 6.5}, + { "celeron_mendocino", 466666666, 7.0}, + { "celeron_mendocino", 500000000, 7.5}, + { "celeron_mendocino", 533333333, 8.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_PentiumIID[] = { - {"pentium2_deschutes", 50000000, 1.0}, - {"pentium2_deschutes", 60000000, 1.0}, - {"pentium2_deschutes", 66666666, 1.0}, - {"pentium2_deschutes", 75000000, 1.5}, - {"pentium2_deschutes", 266666666, 4.0}, - {"pentium2_deschutes", 300000000, 4.5}, - {"pentium2_deschutes", 333333333, 5.0}, - {"pentium2_deschutes", 350000000, 3.5}, - {"pentium2_deschutes", 400000000, 4.0}, - {"pentium2_deschutes", 450000000, 4.5}, - {NULL, 0, 0} + {"pentium2_deschutes", 50000000, 1.0}, + { "pentium2_deschutes", 60000000, 1.0}, + { "pentium2_deschutes", 66666666, 1.0}, + { "pentium2_deschutes", 75000000, 1.5}, + { "pentium2_deschutes", 266666666, 4.0}, + { "pentium2_deschutes", 300000000, 4.5}, + { "pentium2_deschutes", 333333333, 5.0}, + { "pentium2_deschutes", 350000000, 3.5}, + { "pentium2_deschutes", 400000000, 4.0}, + { "pentium2_deschutes", 450000000, 4.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Cyrix3[] = { - {"c3_samuel", 66666666, 1.0}, - {"c3_samuel", 233333333, 3.5}, - {"c3_samuel", 266666666, 4.0}, - {"c3_samuel", 300000000, 4.5}, - {"c3_samuel", 333333333, 5.0}, - {"c3_samuel", 350000000, 3.5}, - {"c3_samuel", 400000000, 4.0}, - {"c3_samuel", 450000000, 4.5}, - {"c3_samuel", 500000000, 5.0}, - {"c3_samuel", 550000000, 5.5}, - {"c3_samuel", 600000000, 6.0}, - {"c3_samuel", 650000000, 6.5}, - {"c3_samuel", 700000000, 7.0}, - {NULL, 0, 0} + {"c3_samuel", 66666666, 1.0}, + { "c3_samuel", 233333333, 3.5}, + { "c3_samuel", 266666666, 4.0}, + { "c3_samuel", 300000000, 4.5}, + { "c3_samuel", 333333333, 5.0}, + { "c3_samuel", 350000000, 3.5}, + { "c3_samuel", 400000000, 4.0}, + { "c3_samuel", 450000000, 4.5}, + { "c3_samuel", 500000000, 5.0}, + { "c3_samuel", 550000000, 5.5}, + { "c3_samuel", 600000000, 6.0}, + { "c3_samuel", 650000000, 6.5}, + { "c3_samuel", 700000000, 7.0}, + { NULL, 0, 0 } }; -static const cpu_legacy_table_t *cputables_8088[4] = {cpus_8088}; -static const cpu_legacy_table_t *cputables_pcjr[4] = {cpus_pcjr}; -static const cpu_legacy_table_t *cputables_europc[4] = {cpus_europc}; -static const cpu_legacy_table_t *cputables_pc1512[4] = {cpus_pc1512}; -static const cpu_legacy_table_t *cputables_8086[4] = {cpus_8086}; -static const cpu_legacy_table_t *cputables_286[4] = {cpus_286}; -static const cpu_legacy_table_t *cputables_ibmat[4] = {cpus_ibmat}; -static const cpu_legacy_table_t *cputables_ps1_m2011[4] = {cpus_ps1_m2011}; -static const cpu_legacy_table_t *cputables_ps2_m30_286_IBM486SLC[4] = {cpus_ps2_m30_286, cpus_IBM486SLC}; -static const cpu_legacy_table_t *cputables_ibmxt286[4] = {cpus_ibmxt286}; -static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC[4] = {cpus_i386SX, cpus_Am386SX, cpus_486SLC}; -static const cpu_legacy_table_t *cputables_ALiM6117[4] = {cpus_ALiM6117}; -static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC_IBM486SLC[4] = {cpus_i386SX, cpus_Am386SX, cpus_486SLC, cpus_IBM486SLC}; -static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC[4] = {cpus_i386DX, cpus_Am386DX, cpus_486DLC}; -static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC_IBM486BL[4] = {cpus_i386DX, cpus_Am386DX, cpus_486DLC, cpus_IBM486BL}; -static const cpu_legacy_table_t *cputables_i486_Am486_Cx486[4] = {cpus_i486, cpus_Am486, cpus_Cx486}; -static const cpu_legacy_table_t *cputables_i486S1_Am486S1_Cx486S1[4] = {cpus_i486S1, cpus_Am486S1, cpus_Cx486S1}; -static const cpu_legacy_table_t *cputables_IBM486SLC[4] = {cpus_IBM486SLC}; -static const cpu_legacy_table_t *cputables_i486_PC330[4] = {cpus_i486_PC330}; -static const cpu_legacy_table_t *cputables_STPCDX[4] = {cpus_STPCDX}; -static const cpu_legacy_table_t *cputables_STPCDX2[4] = {cpus_STPCDX2}; -static const cpu_legacy_table_t *cputables_Pentium5V[4] = {cpus_Pentium5V}; -static const cpu_legacy_table_t *cputables_PentiumS5_WinChip_K5[4] = {cpus_PentiumS5, cpus_WinChip, cpus_K5}; -static const cpu_legacy_table_t *cputables_Pentium3V_WinChip_K5_6x863V[4] = {cpus_Pentium3V, cpus_WinChip, cpus_K5, cpus_6x863V}; -static const cpu_legacy_table_t *cputables_Pentium3V_K5[4] = {cpus_Pentium3V, cpus_K5}; -static const cpu_legacy_table_t *cputables_Pentium_WinChip_K56_6x86[4] = {cpus_Pentium, cpus_WinChip, cpus_K56, cpus_6x86}; -static const cpu_legacy_table_t *cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7[4] = {cpus_Pentium, cpus_WinChip_SS7, cpus_K56_SS7, cpus_6x86SS7}; -static const cpu_legacy_table_t *cputables_PentiumPro[4] = {cpus_PentiumPro}; -static const cpu_legacy_table_t *cputables_PentiumII66[4] = {cpus_PentiumII66}; -static const cpu_legacy_table_t *cputables_PentiumII_Celeron_Cyrix3[4] = {cpus_PentiumII, cpus_Celeron, cpus_Cyrix3}; -static const cpu_legacy_table_t *cputables_Xeon[4] = {cpus_Xeon}; -static const cpu_legacy_table_t *cputables_Celeron_Cyrix3[4] = {cpus_Celeron, cpus_Cyrix3}; -static const cpu_legacy_table_t *cputables_Celeron[4] = {cpus_Celeron}; -static const cpu_legacy_table_t *cputables_PentiumIID_Celeron[4] = {cpus_PentiumIID, cpus_Celeron}; +static const cpu_legacy_table_t *cputables_8088[4] = { cpus_8088 }; +static const cpu_legacy_table_t *cputables_pcjr[4] = { cpus_pcjr }; +static const cpu_legacy_table_t *cputables_europc[4] = { cpus_europc }; +static const cpu_legacy_table_t *cputables_pc1512[4] = { cpus_pc1512 }; +static const cpu_legacy_table_t *cputables_8086[4] = { cpus_8086 }; +static const cpu_legacy_table_t *cputables_286[4] = { cpus_286 }; +static const cpu_legacy_table_t *cputables_ibmat[4] = { cpus_ibmat }; +static const cpu_legacy_table_t *cputables_ps1_m2011[4] = { cpus_ps1_m2011 }; +static const cpu_legacy_table_t *cputables_ps2_m30_286_IBM486SLC[4] = { cpus_ps2_m30_286, cpus_IBM486SLC }; +static const cpu_legacy_table_t *cputables_ibmxt286[4] = { cpus_ibmxt286 }; +static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC[4] = { cpus_i386SX, cpus_Am386SX, cpus_486SLC }; +static const cpu_legacy_table_t *cputables_ALiM6117[4] = { cpus_ALiM6117 }; +static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC_IBM486SLC[4] = { cpus_i386SX, cpus_Am386SX, cpus_486SLC, cpus_IBM486SLC }; +static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC[4] = { cpus_i386DX, cpus_Am386DX, cpus_486DLC }; +static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC_IBM486BL[4] = { cpus_i386DX, cpus_Am386DX, cpus_486DLC, cpus_IBM486BL }; +static const cpu_legacy_table_t *cputables_i486_Am486_Cx486[4] = { cpus_i486, cpus_Am486, cpus_Cx486 }; +static const cpu_legacy_table_t *cputables_i486S1_Am486S1_Cx486S1[4] = { cpus_i486S1, cpus_Am486S1, cpus_Cx486S1 }; +static const cpu_legacy_table_t *cputables_IBM486SLC[4] = { cpus_IBM486SLC }; +static const cpu_legacy_table_t *cputables_i486_PC330[4] = { cpus_i486_PC330 }; +static const cpu_legacy_table_t *cputables_STPCDX[4] = { cpus_STPCDX }; +static const cpu_legacy_table_t *cputables_STPCDX2[4] = { cpus_STPCDX2 }; +static const cpu_legacy_table_t *cputables_Pentium5V[4] = { cpus_Pentium5V }; +static const cpu_legacy_table_t *cputables_PentiumS5_WinChip_K5[4] = { cpus_PentiumS5, cpus_WinChip, cpus_K5 }; +static const cpu_legacy_table_t *cputables_Pentium3V_WinChip_K5_6x863V[4] = { cpus_Pentium3V, cpus_WinChip, cpus_K5, cpus_6x863V }; +static const cpu_legacy_table_t *cputables_Pentium3V_K5[4] = { cpus_Pentium3V, cpus_K5 }; +static const cpu_legacy_table_t *cputables_Pentium_WinChip_K56_6x86[4] = { cpus_Pentium, cpus_WinChip, cpus_K56, cpus_6x86 }; +static const cpu_legacy_table_t *cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7[4] = { cpus_Pentium, cpus_WinChip_SS7, cpus_K56_SS7, cpus_6x86SS7 }; +static const cpu_legacy_table_t *cputables_PentiumPro[4] = { cpus_PentiumPro }; +static const cpu_legacy_table_t *cputables_PentiumII66[4] = { cpus_PentiumII66 }; +static const cpu_legacy_table_t *cputables_PentiumII_Celeron_Cyrix3[4] = { cpus_PentiumII, cpus_Celeron, cpus_Cyrix3 }; +static const cpu_legacy_table_t *cputables_Xeon[4] = { cpus_Xeon }; +static const cpu_legacy_table_t *cputables_Celeron_Cyrix3[4] = { cpus_Celeron, cpus_Cyrix3 }; +static const cpu_legacy_table_t *cputables_Celeron[4] = { cpus_Celeron }; +static const cpu_legacy_table_t *cputables_PentiumIID_Celeron[4] = { cpus_PentiumIID, cpus_Celeron }; const cpu_legacy_machine_t cpu_legacy_table[] = { - {"ibmpc", cputables_8088}, - {"ibmpc82", cputables_8088}, - {"ibmpcjr", cputables_pcjr}, - {"ibmxt", cputables_8088}, - {"ibmxt86", cputables_8088}, - {"americxt", cputables_8088}, - {"amixt", cputables_8088}, - {"portable", cputables_8088}, - {"dtk", cputables_8088}, - {"genxt", cputables_8088}, - {"jukopc", cputables_8088}, - {"openxt", cputables_8088}, - {"pxxt", cputables_8088}, - {"europc", cputables_europc}, - {"tandy", cputables_europc}, - {"tandy1000hx", cputables_europc}, - {"t1000", cputables_8088}, - {"ltxt", cputables_8088}, - {"xi8088", cputables_8088}, - {"zdsupers", cputables_8088}, - {"pc1512", cputables_pc1512}, - {"pc1640", cputables_8086}, - {"pc2086", cputables_8086}, - {"pc3086", cputables_8086}, - {"pc200", cputables_8086}, - {"ppc512", cputables_8086}, - {"deskpro", cputables_8086}, - {"m24", cputables_8086}, - {"iskra3104", cputables_8086}, - {"tandy1000sl2", cputables_8086}, - {"t1200", cputables_8086}, - {"lxt3", cputables_8086}, - {"hed919", cputables_286}, - {"ibmat", cputables_ibmat}, - {"ibmps1es", cputables_ps1_m2011}, - {"ibmps2_m30_286", cputables_ps2_m30_286_IBM486SLC}, - {"ibmxt286", cputables_ibmxt286}, - {"ibmatami", cputables_ibmat}, - {"cmdpc30", cputables_286}, - {"portableii", cputables_286}, - {"portableiii", cputables_286}, - {"mr286", cputables_286}, - {"open_at", cputables_286}, - {"ibmatpx", cputables_ibmat}, - {"ibmatquadtel", cputables_ibmat}, - {"siemens", cputables_286}, - {"t3100e", cputables_286}, - {"quadt286", cputables_286}, - {"tg286m", cputables_286}, - {"ami286", cputables_286}, - {"px286", cputables_286}, - {"award286", cputables_286}, - {"gw286ct", cputables_286}, - {"gdc212m", cputables_286}, - {"super286tr", cputables_286}, - {"spc4200p", cputables_286}, - {"spc4216p", cputables_286}, - {"deskmaster286", cputables_286}, - {"ibmps2_m50", cputables_ps2_m30_286_IBM486SLC}, - {"ibmps1_2121", cputables_i386SX_Am386SX_486SLC}, - {"ibmps1_2121_isa", cputables_i386SX_Am386SX_486SLC}, - {"arb1375", cputables_ALiM6117}, - {"pja511m", cputables_ALiM6117}, - {"ama932j", cputables_i386SX_Am386SX_486SLC}, - {"adi386sx", cputables_i386SX_Am386SX_486SLC}, - {"shuttle386sx", cputables_i386SX_Am386SX_486SLC}, - {"dtk386", cputables_i386SX_Am386SX_486SLC}, - {"awardsx", cputables_i386SX_Am386SX_486SLC}, - {"cmdsl386sx25", cputables_i386SX_Am386SX_486SLC}, - {"kmxc02", cputables_i386SX_Am386SX_486SLC}, - {"megapc", cputables_i386SX_Am386SX_486SLC}, - {"ibmps2_m55sx", cputables_i386SX_Am386SX_486SLC_IBM486SLC}, - {"acc386", cputables_i386DX_Am386DX_486DLC}, - {"ecs386", cputables_i386DX_Am386DX_486DLC}, - {"portableiii386", cputables_i386DX_Am386DX_486DLC}, - {"micronics386", cputables_i386DX_Am386DX_486DLC}, - {"asus386", cputables_i386DX_Am386DX_486DLC}, - {"ustechnologies386", cputables_i386DX_Am386DX_486DLC}, - {"award386dx", cputables_i386DX_Am386DX_486DLC}, - {"ibmps2_m70_type3", cputables_i386DX_Am386DX_486DLC_IBM486BL}, - {"ibmps2_m80", cputables_i386DX_Am386DX_486DLC_IBM486BL}, - {"pb410a", cputables_i486_Am486_Cx486}, - {"acera1g", cputables_i486_Am486_Cx486}, - {"win486", cputables_i486_Am486_Cx486}, - {"ali1429", cputables_i486S1_Am486S1_Cx486S1}, - {"cs4031", cputables_i486S1_Am486S1_Cx486S1}, - {"rycleopardlx", cputables_IBM486SLC}, - {"award486", cputables_i486S1_Am486S1_Cx486S1}, - {"ami486", cputables_i486S1_Am486S1_Cx486S1}, - {"mr486", cputables_i486_Am486_Cx486}, - {"pc330_6571", cputables_i486_PC330}, - {"403tg", cputables_i486_Am486_Cx486}, - {"sis401", cputables_i486_Am486_Cx486}, - {"valuepoint433", cputables_i486_Am486_Cx486}, - {"ami471", cputables_i486_Am486_Cx486}, - {"win471", cputables_i486_Am486_Cx486}, - {"vi15g", cputables_i486_Am486_Cx486}, - {"vli486sv2g", cputables_i486_Am486_Cx486}, - {"dtk486", cputables_i486_Am486_Cx486}, - {"px471", cputables_i486_Am486_Cx486}, - {"486vchd", cputables_i486S1_Am486S1_Cx486S1}, - {"ibmps1_2133", cputables_i486S1_Am486S1_Cx486S1}, - {"vect486vl", cputables_i486S1_Am486S1_Cx486S1}, - {"ibmps2_m70_type4", cputables_i486S1_Am486S1_Cx486S1}, - {"abpb4", cputables_i486_Am486_Cx486}, - {"486ap4", cputables_i486_Am486_Cx486}, - {"486sp3g", cputables_i486_Am486_Cx486}, - {"alfredo", cputables_i486_Am486_Cx486}, - {"ls486e", cputables_i486_Am486_Cx486}, - {"m4li", cputables_i486_Am486_Cx486}, - {"r418", cputables_i486_Am486_Cx486}, - {"4sa2", cputables_i486_Am486_Cx486}, - {"4dps", cputables_i486_Am486_Cx486}, - {"itoxstar", cputables_STPCDX}, - {"arb1479", cputables_STPCDX2}, - {"pcm9340", cputables_STPCDX2}, - {"pcm5330", cputables_STPCDX2}, - {"486vipio2", cputables_i486_Am486_Cx486}, - {"p5mp3", cputables_Pentium5V}, - {"dellxp60", cputables_Pentium5V}, - {"opti560l", cputables_Pentium5V}, - {"ambradp60", cputables_Pentium5V}, - {"valuepointp60", cputables_Pentium5V}, - {"revenge", cputables_Pentium5V}, - {"586mc1", cputables_Pentium5V}, - {"pb520r", cputables_Pentium5V}, - {"excalibur", cputables_Pentium5V}, - {"plato", cputables_PentiumS5_WinChip_K5}, - {"ambradp90", cputables_PentiumS5_WinChip_K5}, - {"430nx", cputables_PentiumS5_WinChip_K5}, - {"acerv30", cputables_PentiumS5_WinChip_K5}, - {"apollo", cputables_PentiumS5_WinChip_K5}, - {"vectra54", cputables_PentiumS5_WinChip_K5}, - {"zappa", cputables_PentiumS5_WinChip_K5}, - {"powermate_v", cputables_PentiumS5_WinChip_K5}, - {"mb500n", cputables_PentiumS5_WinChip_K5}, - {"p54tp4xe", cputables_Pentium3V_WinChip_K5_6x863V}, - {"mr586", cputables_Pentium3V_WinChip_K5_6x863V}, - {"gw2katx", cputables_Pentium3V_WinChip_K5_6x863V}, - {"thor", cputables_Pentium3V_WinChip_K5_6x863V}, - {"mrthor", cputables_Pentium3V_WinChip_K5_6x863V}, - {"endeavor", cputables_Pentium3V_WinChip_K5_6x863V}, - {"pb640", cputables_Pentium3V_WinChip_K5_6x863V}, - {"chariot", cputables_Pentium3V_K5}, - {"acerm3a", cputables_Pentium3V_WinChip_K5_6x863V}, - {"ap53", cputables_Pentium3V_WinChip_K5_6x863V}, - {"8500tuc", cputables_Pentium3V_WinChip_K5_6x863V}, - {"p55t2s", cputables_Pentium3V_WinChip_K5_6x863V}, - {"acerv35n", cputables_Pentium_WinChip_K56_6x86}, - {"p55t2p4", cputables_Pentium_WinChip_K56_6x86}, - {"m7shi", cputables_Pentium_WinChip_K56_6x86}, - {"tc430hx", cputables_Pentium_WinChip_K56_6x86}, - {"equium5200", cputables_Pentium_WinChip_K56_6x86}, - {"pcv240", cputables_Pentium_WinChip_K56_6x86}, - {"p65up5_cp55t2d", cputables_Pentium_WinChip_K56_6x86}, - {"p55tvp4", cputables_Pentium_WinChip_K56_6x86}, - {"8500tvxa", cputables_Pentium_WinChip_K56_6x86}, - {"presario4500", cputables_Pentium_WinChip_K56_6x86}, - {"p55va", cputables_Pentium_WinChip_K56_6x86}, - {"gw2kte", cputables_Pentium_WinChip_K56_6x86}, - {"brio80xx", cputables_Pentium_WinChip_K56_6x86}, - {"pb680", cputables_Pentium_WinChip_K56_6x86}, - {"430vx", cputables_Pentium_WinChip_K56_6x86}, - {"nupro592", cputables_Pentium_WinChip_K56_6x86}, - {"tx97", cputables_Pentium_WinChip_K56_6x86}, - {"an430tx", cputables_Pentium_WinChip_K56_6x86}, - {"ym430tx", cputables_Pentium_WinChip_K56_6x86}, - {"mb540n", cputables_Pentium_WinChip_K56_6x86}, - {"p5mms98", cputables_Pentium_WinChip_K56_6x86}, - {"ficva502", cputables_Pentium_WinChip_K56_6x86}, - {"ficpa2012", cputables_Pentium_WinChip_K56_6x86}, - {"ax59pro", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - {"ficva503p", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - {"ficva503a", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - {"v60n", cputables_PentiumPro}, - {"p65up5_cp6nd", cputables_PentiumPro}, - {"8600ttc", cputables_PentiumPro}, - {"686nx", cputables_PentiumPro}, - {"ap440fx", cputables_PentiumPro}, - {"vs440fx", cputables_PentiumPro}, - {"m6mi", cputables_PentiumPro}, - {"mb600n", cputables_PentiumPro}, - {"p65up5_cpknd", cputables_PentiumII66}, - {"kn97", cputables_PentiumII66}, - {"lx6", cputables_PentiumII66}, - {"spitfire", cputables_PentiumII66}, - {"p6i440e2", cputables_PentiumII66}, - {"p2bls", cputables_PentiumII_Celeron_Cyrix3}, - {"p3bf", cputables_PentiumII_Celeron_Cyrix3}, - {"bf6", cputables_PentiumII_Celeron_Cyrix3}, - {"ax6bc", cputables_PentiumII_Celeron_Cyrix3}, - {"atc6310bxii", cputables_PentiumII_Celeron_Cyrix3}, - {"686bx", cputables_PentiumII_Celeron_Cyrix3}, - {"tsunamiatx", cputables_PentiumII_Celeron_Cyrix3}, - {"p6sba", cputables_PentiumII_Celeron_Cyrix3}, - {"ergox365", cputables_PentiumII_Celeron_Cyrix3}, - {"ficka6130", cputables_PentiumII_Celeron_Cyrix3}, - {"6gxu", cputables_Xeon}, - {"fw6400gx", cputables_Xeon}, - {"s2dge", cputables_Xeon}, - {"s370slm", cputables_Celeron_Cyrix3}, - {"awo671r", cputables_Celeron_Cyrix3}, - {"cubx", cputables_Celeron_Cyrix3}, - {"atc7020bxii", cputables_Celeron_Cyrix3}, - {"ambx133", cputables_Celeron_Cyrix3}, - {"trinity371", cputables_Celeron}, - {"63a", cputables_Celeron_Cyrix3}, - {"apas3", cputables_Celeron_Cyrix3}, - {"wcf681", cputables_Celeron_Cyrix3}, - {"6via90ap", cputables_Celeron_Cyrix3}, - {"p6bap", cputables_Celeron_Cyrix3}, - {"603tcf", cputables_Celeron_Cyrix3}, - {"vpc2007", cputables_PentiumIID_Celeron}, - {NULL, NULL} + {"ibmpc", cputables_8088 }, + { "ibmpc82", cputables_8088 }, + { "ibmpcjr", cputables_pcjr }, + { "ibmxt", cputables_8088 }, + { "ibmxt86", cputables_8088 }, + { "americxt", cputables_8088 }, + { "amixt", cputables_8088 }, + { "portable", cputables_8088 }, + { "dtk", cputables_8088 }, + { "genxt", cputables_8088 }, + { "jukopc", cputables_8088 }, + { "openxt", cputables_8088 }, + { "pxxt", cputables_8088 }, + { "europc", cputables_europc }, + { "tandy", cputables_europc }, + { "tandy1000hx", cputables_europc }, + { "t1000", cputables_8088 }, + { "ltxt", cputables_8088 }, + { "xi8088", cputables_8088 }, + { "zdsupers", cputables_8088 }, + { "pc1512", cputables_pc1512 }, + { "pc1640", cputables_8086 }, + { "pc2086", cputables_8086 }, + { "pc3086", cputables_8086 }, + { "pc200", cputables_8086 }, + { "ppc512", cputables_8086 }, + { "deskpro", cputables_8086 }, + { "m24", cputables_8086 }, + { "iskra3104", cputables_8086 }, + { "tandy1000sl2", cputables_8086 }, + { "t1200", cputables_8086 }, + { "lxt3", cputables_8086 }, + { "hed919", cputables_286 }, + { "ibmat", cputables_ibmat }, + { "ibmps1es", cputables_ps1_m2011 }, + { "ibmps2_m30_286", cputables_ps2_m30_286_IBM486SLC }, + { "ibmxt286", cputables_ibmxt286 }, + { "ibmatami", cputables_ibmat }, + { "cmdpc30", cputables_286 }, + { "portableii", cputables_286 }, + { "portableiii", cputables_286 }, + { "mr286", cputables_286 }, + { "open_at", cputables_286 }, + { "ibmatpx", cputables_ibmat }, + { "ibmatquadtel", cputables_ibmat }, + { "siemens", cputables_286 }, + { "t3100e", cputables_286 }, + { "quadt286", cputables_286 }, + { "tg286m", cputables_286 }, + { "ami286", cputables_286 }, + { "px286", cputables_286 }, + { "award286", cputables_286 }, + { "gw286ct", cputables_286 }, + { "gdc212m", cputables_286 }, + { "super286tr", cputables_286 }, + { "spc4200p", cputables_286 }, + { "spc4216p", cputables_286 }, + { "deskmaster286", cputables_286 }, + { "ibmps2_m50", cputables_ps2_m30_286_IBM486SLC }, + { "ibmps1_2121", cputables_i386SX_Am386SX_486SLC }, + { "ibmps1_2121_isa", cputables_i386SX_Am386SX_486SLC }, + { "arb1375", cputables_ALiM6117 }, + { "pja511m", cputables_ALiM6117 }, + { "ama932j", cputables_i386SX_Am386SX_486SLC }, + { "adi386sx", cputables_i386SX_Am386SX_486SLC }, + { "shuttle386sx", cputables_i386SX_Am386SX_486SLC }, + { "dtk386", cputables_i386SX_Am386SX_486SLC }, + { "awardsx", cputables_i386SX_Am386SX_486SLC }, + { "cmdsl386sx25", cputables_i386SX_Am386SX_486SLC }, + { "kmxc02", cputables_i386SX_Am386SX_486SLC }, + { "megapc", cputables_i386SX_Am386SX_486SLC }, + { "ibmps2_m55sx", cputables_i386SX_Am386SX_486SLC_IBM486SLC }, + { "acc386", cputables_i386DX_Am386DX_486DLC }, + { "ecs386", cputables_i386DX_Am386DX_486DLC }, + { "portableiii386", cputables_i386DX_Am386DX_486DLC }, + { "micronics386", cputables_i386DX_Am386DX_486DLC }, + { "asus386", cputables_i386DX_Am386DX_486DLC }, + { "ustechnologies386", cputables_i386DX_Am386DX_486DLC }, + { "award386dx", cputables_i386DX_Am386DX_486DLC }, + { "ibmps2_m70_type3", cputables_i386DX_Am386DX_486DLC_IBM486BL }, + { "ibmps2_m80", cputables_i386DX_Am386DX_486DLC_IBM486BL }, + { "pb410a", cputables_i486_Am486_Cx486 }, + { "acera1g", cputables_i486_Am486_Cx486 }, + { "win486", cputables_i486_Am486_Cx486 }, + { "ali1429", cputables_i486S1_Am486S1_Cx486S1 }, + { "cs4031", cputables_i486S1_Am486S1_Cx486S1 }, + { "rycleopardlx", cputables_IBM486SLC }, + { "award486", cputables_i486S1_Am486S1_Cx486S1 }, + { "ami486", cputables_i486S1_Am486S1_Cx486S1 }, + { "mr486", cputables_i486_Am486_Cx486 }, + { "pc330_6571", cputables_i486_PC330 }, + { "403tg", cputables_i486_Am486_Cx486 }, + { "sis401", cputables_i486_Am486_Cx486 }, + { "valuepoint433", cputables_i486_Am486_Cx486 }, + { "ami471", cputables_i486_Am486_Cx486 }, + { "win471", cputables_i486_Am486_Cx486 }, + { "vi15g", cputables_i486_Am486_Cx486 }, + { "vli486sv2g", cputables_i486_Am486_Cx486 }, + { "dtk486", cputables_i486_Am486_Cx486 }, + { "px471", cputables_i486_Am486_Cx486 }, + { "486vchd", cputables_i486S1_Am486S1_Cx486S1 }, + { "ibmps1_2133", cputables_i486S1_Am486S1_Cx486S1 }, + { "vect486vl", cputables_i486S1_Am486S1_Cx486S1 }, + { "ibmps2_m70_type4", cputables_i486S1_Am486S1_Cx486S1 }, + { "abpb4", cputables_i486_Am486_Cx486 }, + { "486ap4", cputables_i486_Am486_Cx486 }, + { "486sp3g", cputables_i486_Am486_Cx486 }, + { "alfredo", cputables_i486_Am486_Cx486 }, + { "ls486e", cputables_i486_Am486_Cx486 }, + { "m4li", cputables_i486_Am486_Cx486 }, + { "r418", cputables_i486_Am486_Cx486 }, + { "4sa2", cputables_i486_Am486_Cx486 }, + { "4dps", cputables_i486_Am486_Cx486 }, + { "itoxstar", cputables_STPCDX }, + { "arb1479", cputables_STPCDX2 }, + { "pcm9340", cputables_STPCDX2 }, + { "pcm5330", cputables_STPCDX2 }, + { "486vipio2", cputables_i486_Am486_Cx486 }, + { "p5mp3", cputables_Pentium5V }, + { "dellxp60", cputables_Pentium5V }, + { "opti560l", cputables_Pentium5V }, + { "ambradp60", cputables_Pentium5V }, + { "valuepointp60", cputables_Pentium5V }, + { "revenge", cputables_Pentium5V }, + { "586mc1", cputables_Pentium5V }, + { "pb520r", cputables_Pentium5V }, + { "excalibur", cputables_Pentium5V }, + { "plato", cputables_PentiumS5_WinChip_K5 }, + { "ambradp90", cputables_PentiumS5_WinChip_K5 }, + { "430nx", cputables_PentiumS5_WinChip_K5 }, + { "acerv30", cputables_PentiumS5_WinChip_K5 }, + { "apollo", cputables_PentiumS5_WinChip_K5 }, + { "vectra54", cputables_PentiumS5_WinChip_K5 }, + { "zappa", cputables_PentiumS5_WinChip_K5 }, + { "powermate_v", cputables_PentiumS5_WinChip_K5 }, + { "mb500n", cputables_PentiumS5_WinChip_K5 }, + { "p54tp4xe", cputables_Pentium3V_WinChip_K5_6x863V }, + { "mr586", cputables_Pentium3V_WinChip_K5_6x863V }, + { "gw2katx", cputables_Pentium3V_WinChip_K5_6x863V }, + { "thor", cputables_Pentium3V_WinChip_K5_6x863V }, + { "mrthor", cputables_Pentium3V_WinChip_K5_6x863V }, + { "endeavor", cputables_Pentium3V_WinChip_K5_6x863V }, + { "pb640", cputables_Pentium3V_WinChip_K5_6x863V }, + { "chariot", cputables_Pentium3V_K5 }, + { "acerm3a", cputables_Pentium3V_WinChip_K5_6x863V }, + { "ap53", cputables_Pentium3V_WinChip_K5_6x863V }, + { "8500tuc", cputables_Pentium3V_WinChip_K5_6x863V }, + { "p55t2s", cputables_Pentium3V_WinChip_K5_6x863V }, + { "acerv35n", cputables_Pentium_WinChip_K56_6x86 }, + { "p55t2p4", cputables_Pentium_WinChip_K56_6x86 }, + { "m7shi", cputables_Pentium_WinChip_K56_6x86 }, + { "tc430hx", cputables_Pentium_WinChip_K56_6x86 }, + { "equium5200", cputables_Pentium_WinChip_K56_6x86 }, + { "pcv240", cputables_Pentium_WinChip_K56_6x86 }, + { "p65up5_cp55t2d", cputables_Pentium_WinChip_K56_6x86 }, + { "p55tvp4", cputables_Pentium_WinChip_K56_6x86 }, + { "8500tvxa", cputables_Pentium_WinChip_K56_6x86 }, + { "presario4500", cputables_Pentium_WinChip_K56_6x86 }, + { "p55va", cputables_Pentium_WinChip_K56_6x86 }, + { "gw2kte", cputables_Pentium_WinChip_K56_6x86 }, + { "brio80xx", cputables_Pentium_WinChip_K56_6x86 }, + { "pb680", cputables_Pentium_WinChip_K56_6x86 }, + { "430vx", cputables_Pentium_WinChip_K56_6x86 }, + { "nupro592", cputables_Pentium_WinChip_K56_6x86 }, + { "tx97", cputables_Pentium_WinChip_K56_6x86 }, + { "an430tx", cputables_Pentium_WinChip_K56_6x86 }, + { "ym430tx", cputables_Pentium_WinChip_K56_6x86 }, + { "mb540n", cputables_Pentium_WinChip_K56_6x86 }, + { "p5mms98", cputables_Pentium_WinChip_K56_6x86 }, + { "ficva502", cputables_Pentium_WinChip_K56_6x86 }, + { "ficpa2012", cputables_Pentium_WinChip_K56_6x86 }, + { "ax59pro", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, + { "ficva503p", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, + { "ficva503a", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, + { "v60n", cputables_PentiumPro }, + { "p65up5_cp6nd", cputables_PentiumPro }, + { "8600ttc", cputables_PentiumPro }, + { "686nx", cputables_PentiumPro }, + { "ap440fx", cputables_PentiumPro }, + { "vs440fx", cputables_PentiumPro }, + { "m6mi", cputables_PentiumPro }, + { "mb600n", cputables_PentiumPro }, + { "p65up5_cpknd", cputables_PentiumII66 }, + { "kn97", cputables_PentiumII66 }, + { "lx6", cputables_PentiumII66 }, + { "spitfire", cputables_PentiumII66 }, + { "p6i440e2", cputables_PentiumII66 }, + { "p2bls", cputables_PentiumII_Celeron_Cyrix3 }, + { "p3bf", cputables_PentiumII_Celeron_Cyrix3 }, + { "bf6", cputables_PentiumII_Celeron_Cyrix3 }, + { "ax6bc", cputables_PentiumII_Celeron_Cyrix3 }, + { "atc6310bxii", cputables_PentiumII_Celeron_Cyrix3 }, + { "686bx", cputables_PentiumII_Celeron_Cyrix3 }, + { "tsunamiatx", cputables_PentiumII_Celeron_Cyrix3 }, + { "p6sba", cputables_PentiumII_Celeron_Cyrix3 }, + { "ergox365", cputables_PentiumII_Celeron_Cyrix3 }, + { "ficka6130", cputables_PentiumII_Celeron_Cyrix3 }, + { "6gxu", cputables_Xeon }, + { "fw6400gx", cputables_Xeon }, + { "s2dge", cputables_Xeon }, + { "s370slm", cputables_Celeron_Cyrix3 }, + { "awo671r", cputables_Celeron_Cyrix3 }, + { "cubx", cputables_Celeron_Cyrix3 }, + { "atc7020bxii", cputables_Celeron_Cyrix3 }, + { "ambx133", cputables_Celeron_Cyrix3 }, + { "trinity371", cputables_Celeron }, + { "63a", cputables_Celeron_Cyrix3 }, + { "apas3", cputables_Celeron_Cyrix3 }, + { "wcf681", cputables_Celeron_Cyrix3 }, + { "6via90ap", cputables_Celeron_Cyrix3 }, + { "p6bap", cputables_Celeron_Cyrix3 }, + { "603tcf", cputables_Celeron_Cyrix3 }, + { "vpc2007", cputables_PentiumIID_Celeron }, + { NULL, NULL } }; diff --git a/src/cpu/fpu.c b/src/cpu/fpu.c index 2d74b256a..f75d07231 100644 --- a/src/cpu/fpu.c +++ b/src/cpu/fpu.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * FPU type handler. + * FPU type handler. * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -25,77 +25,71 @@ #include <86box/86box.h> #include "cpu.h" - #ifdef ENABLE_FPU_LOG int fpu_do_log = ENABLE_FPU_LOG; - void fpu_log(const char *fmt, ...) { va_list ap; if (fpu_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define fpu_log(fmt, ...) +# define fpu_log(fmt, ...) #endif - int fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name) { - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int fpu_type = fpus[0].type; - int c = 0; + const CPU *cpu_s = &cpu_family->cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int fpu_type = fpus[0].type; + int c = 0; while (fpus[c].internal_name) { - if (!strcmp(internal_name, fpus[c].internal_name)) - fpu_type = fpus[c].type; - c++; + if (!strcmp(internal_name, fpus[c].internal_name)) + fpu_type = fpus[c].type; + c++; } return fpu_type; } - const char * fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type) { const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int c = 0; + const FPU *fpus = cpu_s->fpus; + int c = 0; while (fpus[c].internal_name) { - if (fpus[c].type == type) - return fpus[c].internal_name; - c++; + if (fpus[c].type == type) + return fpus[c].internal_name; + c++; } return fpus[0].internal_name; } - const char * fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c) { const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; + const FPU *fpus = cpu_s->fpus; return fpus[c].name; } - int fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c) { const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; + const FPU *fpus = cpu_s->fpus; return fpus[c].type; } diff --git a/src/cpu/x86.c b/src/cpu/x86.c index bf5b168db..eb1dc463f 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Functions common to all emulated x86 CPU's. + * Functions common to all emulated x86 CPU's. * - * Authors: Andrew Jenner, - * Miran Grca, + * Authors: Andrew Jenner, + * Miran Grca, * - * Copyright 2015-2020 Andrew Jenner. - * Copyright 2016-2020 Miran Grca. + * Copyright 2015-2020 Andrew Jenner. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -43,7 +43,7 @@ uint8_t opcode; /* The tables to speed up the setting of the Z, N, and P cpu_state.flags. */ -uint8_t znptable8[256]; +uint8_t znptable8[256]; uint16_t znptable16[65536]; /* A 16-bit zero, needed because some speed-up arrays contain pointers to it. */ @@ -52,7 +52,7 @@ uint16_t zero = 0; /* MOD and R/M stuff. */ uint16_t *mod1add[2][8]; uint32_t *mod1seg[8]; -uint32_t rmdat; +uint32_t rmdat; /* XT CPU multiplier. */ uint64_t xt_cpu_multi; @@ -72,13 +72,11 @@ uint32_t easeg; /* This is for the OPTI 283 special reset handling mode. */ int reset_on_hlt, hlt_reset_pending; - #ifdef ENABLE_X86_LOG -void dumpregs(int); +void dumpregs(int); int x86_do_log = ENABLE_X86_LOG; -int indump = 0; - +int indump = 0; static void x808x_log(const char *fmt, ...) @@ -86,60 +84,58 @@ x808x_log(const char *fmt, ...) va_list ap; if (x808x_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } - void dumpregs(int force) { - int c; + int c; char *seg_names[4] = { "ES", "CS", "SS", "DS" }; /* Only dump when needed, and only once.. */ if (indump || (!force && !dump_on_exit)) - return; + return; x808x_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", - cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); + cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); x808x_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins); for (c = 0; c < 4; c++) { - x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_names[c], _opseg[c]->base, _opseg[c]->limit, - _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); + x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_names[c], _opseg[c]->base, _opseg[c]->limit, + _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); } if (is386) { - x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); - x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); - x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); - x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); - x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); - x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); - x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", - (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", - (use32) ? 32 : 16, (stack32) ? 32 : 16); - x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); - x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", - EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); + x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); + x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); + x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); + x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); + x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); + x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); + x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", + (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", + (use32) ? 32 : 16, (stack32) ? 32 : 16); + x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); + x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", + EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); } else { - x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); - x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", - AX, BX, CX, DX, DI, SI, BP, SP); + x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); + x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", + AX, BX, CX, DX, DI, SI, BP, SP); } x808x_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum); x87_dumpregs(); indump = 0; } #else -#define x808x_log(fmt, ...) +# define x808x_log(fmt, ...) #endif - /* Preparation of the various arrays needed to speed up the MOD and R/M work. */ static void makemod1table(void) @@ -160,143 +156,141 @@ makemod1table(void) mod1add[1][5] = &zero; mod1add[1][6] = &zero; mod1add[1][7] = &zero; - mod1seg[0] = &ds; - mod1seg[1] = &ds; - mod1seg[2] = &ss; - mod1seg[3] = &ss; - mod1seg[4] = &ds; - mod1seg[5] = &ds; - mod1seg[6] = &ss; - mod1seg[7] = &ds; + mod1seg[0] = &ds; + mod1seg[1] = &ds; + mod1seg[2] = &ss; + mod1seg[3] = &ss; + mod1seg[4] = &ds; + mod1seg[5] = &ds; + mod1seg[6] = &ss; + mod1seg[7] = &ds; } - /* Prepare the ZNP table needed to speed up the setting of the Z, N, and P cpu_state.flags. */ static void makeznptable(void) { int c, d, e; for (c = 0; c < 256; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable8[c] = 0; - else - znptable8[c] = P_FLAG; + d = 0; + for (e = 0; e < 8; e++) { + if (c & (1 << e)) + d++; + } + if (d & 1) + znptable8[c] = 0; + else + znptable8[c] = P_FLAG; #ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); + if (c == 0xb1) + x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); #endif - if (!c) - znptable8[c] |= Z_FLAG; - if (c & 0x80) - znptable8[c] |= N_FLAG; + if (!c) + znptable8[c] |= Z_FLAG; + if (c & 0x80) + znptable8[c] |= N_FLAG; } for (c = 0; c < 65536; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable16[c] = 0; - else - znptable16[c] = P_FLAG; + d = 0; + for (e = 0; e < 8; e++) { + if (c & (1 << e)) + d++; + } + if (d & 1) + znptable16[c] = 0; + else + znptable16[c] = P_FLAG; #ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); - if (c == 0x65b1) - x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); + if (c == 0xb1) + x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); + if (c == 0x65b1) + x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); #endif - if (!c) - znptable16[c] |= Z_FLAG; - if (c & 0x8000) - znptable16[c] |= N_FLAG; + if (!c) + znptable16[c] |= Z_FLAG; + if (c & 0x8000) + znptable16[c] |= N_FLAG; } } - /* Common reset function. */ static void reset_common(int hard) { #ifdef ENABLE_808X_LOG if (hard) - x808x_log("x86 reset\n"); + x808x_log("x86 reset\n"); #endif if (!hard && reset_on_hlt) { - hlt_reset_pending++; - pclog("hlt_reset_pending = %i\n", hlt_reset_pending); - if (hlt_reset_pending == 2) - hlt_reset_pending = 0; - else - return; + hlt_reset_pending++; + pclog("hlt_reset_pending = %i\n", hlt_reset_pending); + if (hlt_reset_pending == 2) + hlt_reset_pending = 0; + else + return; } /* Make sure to gracefully leave SMM. */ if (in_smm) - leave_smm(); + leave_smm(); /* Needed for the ALi M1533. */ if (is486 && (hard || soft_reset_pci)) { - pci_reset(); - if (!hard && soft_reset_pci) { - dma_reset(); - /* TODO: Hack, but will do for time being, because all AT machines currently are 286+, - and vice-versa. */ - dma_set_at(is286); - device_reset_all(); - } + pci_reset(); + if (!hard && soft_reset_pci) { + dma_reset(); + /* TODO: Hack, but will do for time being, because all AT machines currently are 286+, + and vice-versa. */ + dma_set_at(is286); + device_reset_all(); + } } - use32 = 0; + use32 = 0; cpu_cur_status = 0; - stack32 = 0; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - msw = 0; + stack32 = 0; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + msw = 0; if (hascache) - cr0 = 1 << 30; + cr0 = 1 << 30; else - cr0 = 0; + cr0 = 0; cpu_cache_int_enabled = 0; cpu_update_waitstates(); - cr4 = 0; + cr4 = 0; cpu_state.eflags = 0; - cgate32 = 0; + cgate32 = 0; if (is286) { - loadcs(0xF000); - cpu_state.pc = 0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - if (is6117) - rammask |= 0x03000000; + loadcs(0xF000); + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + if (is6117) + rammask |= 0x03000000; } - idt.base = 0; + idt.base = 0; cpu_state.flags = 2; - trap = 0; + trap = 0; idt.limit = is386 ? 0x03ff : 0xffff; if (is386 || hard) - EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; if (hard) { - makeznptable(); - resetreadlookup(); - makemod1table(); - cpu_set_edx(); - mmu_perm = 4; + makeznptable(); + resetreadlookup(); + makemod1table(); + cpu_set_edx(); + mmu_perm = 4; } x86seg_reset(); #ifdef USE_DYNAREC if (hard) - codegen_reset(); + codegen_reset(); #endif if (!hard) - flushmmucache(); + flushmmucache(); x86_was_reset = 1; cpu_alt_reset = 0; @@ -304,12 +298,12 @@ reset_common(int hard) in_smm = smi_latched = 0; smi_line = smm_in_hlt = 0; - smi_block = 0; + smi_block = 0; if (hard) { - if (is486) - smbase = is_am486dxl ? 0x00060000 : 0x00030000; - ppi_reset(); + if (is486) + smbase = is_am486dxl ? 0x00060000 : 0x00030000; + ppi_reset(); } in_sys = 0; @@ -317,17 +311,16 @@ reset_common(int hard) alt_access = cpu_end_block_after_ins = 0; if (hard) { - reset_on_hlt = hlt_reset_pending = 0; - cache_index = 0; - memset(_tr, 0x00, sizeof(_tr)); - memset(_cache, 0x00, sizeof(_cache)); + reset_on_hlt = hlt_reset_pending = 0; + cache_index = 0; + memset(_tr, 0x00, sizeof(_tr)); + memset(_cache, 0x00, sizeof(_cache)); } if (!is286) - reset_808x(hard); + reset_808x(hard); } - /* Hard reset. */ void resetx86(void) @@ -337,13 +330,12 @@ resetx86(void) soft_reset_mask = 0; } - /* Soft reset. */ void softresetx86(void) { if (soft_reset_mask) - return; + return; if (ibm8514_enabled || xga_enabled) vga_on = 1; @@ -351,7 +343,6 @@ softresetx86(void) reset_common(0); } - /* Actual hard reset. */ void hardresetx86(void) diff --git a/src/cpu/x86.h b/src/cpu/x86.h index 32a3317ea..337619fa4 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -7,77 +7,78 @@ This distinction is used by the dynarec; a block that hits an 'expected' exception would be compiled, a block that hits an 'unexpected' exception would be rejected so that we don't end up with an unnecessarily short block*/ -#define ABRT_EXPECTED 0x80 +#define ABRT_EXPECTED 0x80 -extern uint8_t opcode, opcode2; -extern uint8_t flags_p; -extern uint8_t znptable8[256]; +extern uint8_t opcode, opcode2; +extern uint8_t flags_p; +extern uint8_t znptable8[256]; -extern uint16_t zero, oldcs; -extern uint16_t lastcs, lastpc; +extern uint16_t zero, oldcs; +extern uint16_t lastcs, lastpc; extern uint16_t *mod1add[2][8]; -extern uint16_t znptable16[65536]; +extern uint16_t znptable16[65536]; -extern int x86_was_reset, trap; -extern int codegen_flat_ss, codegen_flat_ds; -extern int timetolive, keyboardtimer, trap; -extern int optype, stack32; -extern int oldcpl, cgate32, cpl_override; -extern int nmi_enable; -extern int oddeven, inttype; +extern int x86_was_reset, trap; +extern int codegen_flat_ss, codegen_flat_ds; +extern int timetolive, keyboardtimer, trap; +extern int optype, stack32; +extern int oldcpl, cgate32, cpl_override; +extern int nmi_enable; +extern int oddeven, inttype; -extern uint32_t use32; -extern uint32_t rmdat, easeg; -extern uint32_t oxpc, flags_zn; -extern uint32_t abrt_error; -extern uint32_t backupregs[16]; +extern uint32_t use32; +extern uint32_t rmdat, easeg; +extern uint32_t oxpc, flags_zn; +extern uint32_t abrt_error; +extern uint32_t backupregs[16]; extern uint32_t *mod1seg[8]; extern uint32_t *eal_r, *eal_w; -#define fetchdat rmdat +#define fetchdat rmdat #define setznp168 setznp16 -#define getr8(r) ((r&4)?cpu_state.regs[r&3].b.h:cpu_state.regs[r&3].b.l) -#define getr16(r) cpu_state.regs[r].w -#define getr32(r) cpu_state.regs[r].l +#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) +#define getr16(r) cpu_state.regs[r].w +#define getr32(r) cpu_state.regs[r].l -#define setr8(r,v) if (r&4) cpu_state.regs[r&3].b.h=v; \ - else cpu_state.regs[r&3].b.l=v; -#define setr16(r,v) cpu_state.regs[r].w=v -#define setr32(r,v) cpu_state.regs[r].l=v +#define setr8(r, v) \ + if (r & 4) \ + cpu_state.regs[r & 3].b.h = v; \ + else \ + cpu_state.regs[r & 3].b.l = v; +#define setr16(r, v) cpu_state.regs[r].w = v +#define setr32(r, v) cpu_state.regs[r].l = v -#define fetchea() { \ - rmdat = readmemb(cs + pc); \ - pc++; \ - reg = (rmdat >> 3) & 7; \ - mod = (rmdat >> 6) & 3; \ - rm = rmdat & 7; \ - if (mod!=3) \ - fetcheal(); \ - } +#define fetchea() \ + { \ + rmdat = readmemb(cs + pc); \ + pc++; \ + reg = (rmdat >> 3) & 7; \ + mod = (rmdat >> 6) & 3; \ + rm = rmdat & 7; \ + if (mod != 3) \ + fetcheal(); \ + } -#define JMP 1 -#define CALL 2 -#define IRET 3 +#define JMP 1 +#define CALL 2 +#define IRET 3 #define OPTYPE_INT 4 - -enum -{ - ABRT_NONE = 0, - ABRT_GEN, - ABRT_TS = 0xA, - ABRT_NP = 0xB, - ABRT_SS = 0xC, - ABRT_GPF = 0xD, - ABRT_PF = 0xE, - ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ +enum { + ABRT_NONE = 0, + ABRT_GEN, + ABRT_TS = 0xA, + ABRT_NP = 0xB, + ABRT_SS = 0xC, + ABRT_GPF = 0xD, + ABRT_PF = 0xE, + ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ }; - -extern void x86_doabrt(int x86_abrt); -extern void x86illegal(); -extern void x86seg_reset(); -extern void x86gpf(char *s, uint16_t error); -extern void x86gpf_expected(char *s, uint16_t error); +extern void x86_doabrt(int x86_abrt); +extern void x86illegal(void); +extern void x86seg_reset(void); +extern void x86gpf(char *s, uint16_t error); +extern void x86gpf_expected(char *s, uint16_t error); diff --git a/src/cpu/x86_flags.h b/src/cpu/x86_flags.h index b46755e90..b8b1a706a 100644 --- a/src/cpu/x86_flags.h +++ b/src/cpu/x86_flags.h @@ -1,783 +1,825 @@ extern int tempc; -enum -{ - FLAGS_UNKNOWN, +enum { + FLAGS_UNKNOWN, - FLAGS_ZN8, - FLAGS_ZN16, - FLAGS_ZN32, + FLAGS_ZN8, + FLAGS_ZN16, + FLAGS_ZN32, - FLAGS_ADD8, - FLAGS_ADD16, - FLAGS_ADD32, + FLAGS_ADD8, + FLAGS_ADD16, + FLAGS_ADD32, - FLAGS_SUB8, - FLAGS_SUB16, - FLAGS_SUB32, + FLAGS_SUB8, + FLAGS_SUB16, + FLAGS_SUB32, - FLAGS_SHL8, - FLAGS_SHL16, - FLAGS_SHL32, + FLAGS_SHL8, + FLAGS_SHL16, + FLAGS_SHL32, - FLAGS_SHR8, - FLAGS_SHR16, - FLAGS_SHR32, + FLAGS_SHR8, + FLAGS_SHR16, + FLAGS_SHR32, - FLAGS_SAR8, - FLAGS_SAR16, - FLAGS_SAR32, + FLAGS_SAR8, + FLAGS_SAR16, + FLAGS_SAR32, #ifdef USE_NEW_DYNAREC - FLAGS_ROL8, - FLAGS_ROL16, - FLAGS_ROL32, + FLAGS_ROL8, + FLAGS_ROL16, + FLAGS_ROL32, - FLAGS_ROR8, - FLAGS_ROR16, - FLAGS_ROR32, + FLAGS_ROR8, + FLAGS_ROR16, + FLAGS_ROR32, #endif - FLAGS_INC8, - FLAGS_INC16, - FLAGS_INC32, + FLAGS_INC8, + FLAGS_INC16, + FLAGS_INC32, - FLAGS_DEC8, - FLAGS_DEC16, - FLAGS_DEC32 + FLAGS_DEC8, + FLAGS_DEC16, + FLAGS_DEC32 #ifdef USE_NEW_DYNAREC -, + , - FLAGS_ADC8, - FLAGS_ADC16, - FLAGS_ADC32, + FLAGS_ADC8, + FLAGS_ADC16, + FLAGS_ADC32, - FLAGS_SBC8, - FLAGS_SBC16, - FLAGS_SBC32 + FLAGS_SBC8, + FLAGS_SBC16, + FLAGS_SBC32 #endif }; -static __inline int ZF_SET() +static __inline int +ZF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - case FLAGS_ADC16: - case FLAGS_ADC32: - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: #endif - return !cpu_state.flags_res; + return !cpu_state.flags_res; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & Z_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & Z_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int NF_SET() +static __inline int +NF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - case FLAGS_SBC8: + case FLAGS_ADC8: + case FLAGS_SBC8: #endif - return cpu_state.flags_res & 0x80; + return cpu_state.flags_res & 0x80; - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC16: - case FLAGS_SBC16: + case FLAGS_ADC16: + case FLAGS_SBC16: #endif - return cpu_state.flags_res & 0x8000; + return cpu_state.flags_res & 0x8000; - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC32: - case FLAGS_SBC32: + case FLAGS_ADC32: + case FLAGS_SBC32: #endif - return cpu_state.flags_res & 0x80000000; + return cpu_state.flags_res & 0x80000000; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & N_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & N_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int PF_SET() +static __inline int +PF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - case FLAGS_ADC16: - case FLAGS_ADC32: - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: #endif - return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; + return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & P_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & P_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int VF_SET() +static __inline int +VF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + return 0; #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: + case FLAGS_ADC8: #endif - case FLAGS_ADD8: - case FLAGS_INC8: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_ADD8: + case FLAGS_INC8: + return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); #ifdef USE_NEW_DYNAREC - case FLAGS_ADC16: + case FLAGS_ADC16: #endif - case FLAGS_ADD16: - case FLAGS_INC16: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_ADD16: + case FLAGS_INC16: + return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); #ifdef USE_NEW_DYNAREC - case FLAGS_ADC32: + case FLAGS_ADC32: #endif - case FLAGS_ADD32: - case FLAGS_INC32: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); + case FLAGS_ADD32: + case FLAGS_INC32: + return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC8: + case FLAGS_SBC8: #endif - case FLAGS_SUB8: - case FLAGS_DEC8: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_SUB8: + case FLAGS_DEC8: + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC16: + case FLAGS_SBC16: #endif - case FLAGS_SUB16: - case FLAGS_DEC16: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_SUB16: + case FLAGS_DEC16: + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC32: + case FLAGS_SBC32: #endif - case FLAGS_SUB32: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); + case FLAGS_SUB32: + case FLAGS_DEC32: + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); - case FLAGS_SHL8: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80); - case FLAGS_SHL16: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000); - case FLAGS_SHL32: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000); + case FLAGS_SHL8: + return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80); + case FLAGS_SHL16: + return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000); + case FLAGS_SHL32: + return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000); - case FLAGS_SHR8: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80)); - case FLAGS_SHR16: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000)); - case FLAGS_SHR32: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); + case FLAGS_SHR8: + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80)); + case FLAGS_SHR16: + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000)); + case FLAGS_SHR32: + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; - case FLAGS_ROL16: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; - case FLAGS_ROL32: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; + case FLAGS_ROL8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; + case FLAGS_ROL16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; + case FLAGS_ROL32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; - case FLAGS_ROR8: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; - case FLAGS_ROR16: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; - case FLAGS_ROR32: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; + case FLAGS_ROR8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; + case FLAGS_ROR16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; + case FLAGS_ROR32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & V_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & V_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int AF_SET() +static __inline int +AF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + return 0; - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10; + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10; #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); - case FLAGS_ADC16: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); - case FLAGS_ADC32: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_ADC8: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); #endif - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; #ifdef USE_NEW_DYNAREC - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: - return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || - ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & A_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & A_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int CF_SET() +static __inline int +CF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ADD8: - return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; - case FLAGS_ADD16: - return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; - case FLAGS_ADD32: - return (cpu_state.flags_res < cpu_state.flags_op1); + switch (cpu_state.flags_op) { + case FLAGS_ADD8: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; + case FLAGS_ADD16: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; + case FLAGS_ADD32: + return (cpu_state.flags_res < cpu_state.flags_op1); #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); - case FLAGS_ADC16: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); - case FLAGS_ADC32: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_ADC8: + return (cpu_state.flags_res < cpu_state.flags_op1) || (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return (cpu_state.flags_res < cpu_state.flags_op1) || (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return (cpu_state.flags_res < cpu_state.flags_op1) || (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); #endif - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - return (cpu_state.flags_op1 < cpu_state.flags_op2); + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + return (cpu_state.flags_op1 < cpu_state.flags_op2); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: - return (cpu_state.flags_op1 < cpu_state.flags_op2) || - (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return (cpu_state.flags_op1 < cpu_state.flags_op2) || (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); #endif - case FLAGS_SHL8: - return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; - case FLAGS_SHL16: - return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; - case FLAGS_SHL32: - return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; + case FLAGS_SHL8: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; + case FLAGS_SHL16: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; + case FLAGS_SHL32: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR8: - return ((int8_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR16: - return ((int16_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR32: - return ((int32_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SAR8: + return ((int8_t) cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SAR16: + return ((int16_t) cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SAR32: + return ((int32_t) cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - return 0; + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + return 0; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - return cpu_state.flags_res & 1; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + return cpu_state.flags_res & 1; - case FLAGS_ROR8: - return (cpu_state.flags_res & 0x80) ? 1 : 0; - case FLAGS_ROR16: - return (cpu_state.flags_res & 0x8000) ? 1 :0; - case FLAGS_ROR32: - return (cpu_state.flags_res & 0x80000000) ? 1 : 0; + case FLAGS_ROR8: + return (cpu_state.flags_res & 0x80) ? 1 : 0; + case FLAGS_ROR16: + return (cpu_state.flags_res & 0x8000) ? 1 : 0; + case FLAGS_ROR32: + return (cpu_state.flags_res & 0x80000000) ? 1 : 0; #endif - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_UNKNOWN: - return cpu_state.flags & C_FLAG; + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_UNKNOWN: + return cpu_state.flags & C_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline void flags_rebuild() -{ - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - uint16_t tempf = 0; - if (CF_SET()) tempf |= C_FLAG; - if (PF_SET()) tempf |= P_FLAG; - if (AF_SET()) tempf |= A_FLAG; - if (ZF_SET()) tempf |= Z_FLAG; - if (NF_SET()) tempf |= N_FLAG; - if (VF_SET()) tempf |= V_FLAG; - cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; - cpu_state.flags_op = FLAGS_UNKNOWN; - } -} - -static __inline void flags_extract() +static __inline void +flags_rebuild(void) { + if (cpu_state.flags_op != FLAGS_UNKNOWN) { + uint16_t tempf = 0; + if (CF_SET()) + tempf |= C_FLAG; + if (PF_SET()) + tempf |= P_FLAG; + if (AF_SET()) + tempf |= A_FLAG; + if (ZF_SET()) + tempf |= Z_FLAG; + if (NF_SET()) + tempf |= N_FLAG; + if (VF_SET()) + tempf |= V_FLAG; + cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; cpu_state.flags_op = FLAGS_UNKNOWN; + } } -static __inline void flags_rebuild_c() +static __inline void +flags_extract(void) { - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - if (CF_SET()) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - } + cpu_state.flags_op = FLAGS_UNKNOWN; +} + +static __inline void +flags_rebuild_c(void) +{ + if (cpu_state.flags_op != FLAGS_UNKNOWN) { + if (CF_SET()) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + } } #ifdef USE_NEW_DYNAREC -static __inline int flags_res_valid() +static __inline int +flags_res_valid(void) { - if (cpu_state.flags_op == FLAGS_UNKNOWN || - (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) - return 0; + if (cpu_state.flags_op == FLAGS_UNKNOWN || (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) + return 0; - return 1; + return 1; } #endif -static __inline void setznp8(uint8_t val) +static __inline void +setznp8(uint8_t val) { - cpu_state.flags_op = FLAGS_ZN8; - cpu_state.flags_res = val; + cpu_state.flags_op = FLAGS_ZN8; + cpu_state.flags_res = val; } -static __inline void setznp16(uint16_t val) +static __inline void +setznp16(uint16_t val) { - cpu_state.flags_op = FLAGS_ZN16; - cpu_state.flags_res = val; + cpu_state.flags_op = FLAGS_ZN16; + cpu_state.flags_res = val; } -static __inline void setznp32(uint32_t val) +static __inline void +setznp32(uint32_t val) { - cpu_state.flags_op = FLAGS_ZN32; - cpu_state.flags_res = val; + cpu_state.flags_op = FLAGS_ZN32; + cpu_state.flags_res = val; } #define set_flags_shift(op, orig, shift, res) \ - cpu_state.flags_op = op; \ - cpu_state.flags_res = res; \ - cpu_state.flags_op1 = orig; \ - cpu_state.flags_op2 = shift; + cpu_state.flags_op = op; \ + cpu_state.flags_res = res; \ + cpu_state.flags_op1 = orig; \ + cpu_state.flags_op2 = shift; #ifdef USE_NEW_DYNAREC -#define set_flags_rotate(op, res) \ - cpu_state.flags_op = op; \ +# define set_flags_rotate(op, res) \ + cpu_state.flags_op = op; \ cpu_state.flags_res = res; #endif -static __inline void setadd8(uint8_t a, uint8_t b) +static __inline void +setadd8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_ADD8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xff; + cpu_state.flags_op = FLAGS_ADD8; } -static __inline void setadd16(uint16_t a, uint16_t b) +static __inline void +setadd16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_ADD16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xffff; + cpu_state.flags_op = FLAGS_ADD16; } -static __inline void setadd32(uint32_t a, uint32_t b) +static __inline void +setadd32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_ADD32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b; + cpu_state.flags_op = FLAGS_ADD32; } -static __inline void setadd8nc(uint8_t a, uint8_t b) +static __inline void +setadd8nc(uint8_t a, uint8_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_INC8; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xff; + cpu_state.flags_op = FLAGS_INC8; } -static __inline void setadd16nc(uint16_t a, uint16_t b) +static __inline void +setadd16nc(uint16_t a, uint16_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_INC16; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xffff; + cpu_state.flags_op = FLAGS_INC16; } -static __inline void setadd32nc(uint32_t a, uint32_t b) +static __inline void +setadd32nc(uint32_t a, uint32_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_INC32; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b; + cpu_state.flags_op = FLAGS_INC32; } -static __inline void setsub8(uint8_t a, uint8_t b) +static __inline void +setsub8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_SUB8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xff; + cpu_state.flags_op = FLAGS_SUB8; } -static __inline void setsub16(uint16_t a, uint16_t b) +static __inline void +setsub16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_SUB16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xffff; + cpu_state.flags_op = FLAGS_SUB16; } -static __inline void setsub32(uint32_t a, uint32_t b) +static __inline void +setsub32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_SUB32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - b; + cpu_state.flags_op = FLAGS_SUB32; } -static __inline void setsub8nc(uint8_t a, uint8_t b) +static __inline void +setsub8nc(uint8_t a, uint8_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_DEC8; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xff; + cpu_state.flags_op = FLAGS_DEC8; } -static __inline void setsub16nc(uint16_t a, uint16_t b) +static __inline void +setsub16nc(uint16_t a, uint16_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_DEC16; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xffff; + cpu_state.flags_op = FLAGS_DEC16; } -static __inline void setsub32nc(uint32_t a, uint32_t b) +static __inline void +setsub32nc(uint32_t a, uint32_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_DEC32; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - b; + cpu_state.flags_op = FLAGS_DEC32; } #ifdef USE_NEW_DYNAREC -static __inline void setadc8(uint8_t a, uint8_t b) +static __inline void +setadc8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b + tempc) & 0xff; - cpu_state.flags_op = FLAGS_ADC8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xff; + cpu_state.flags_op = FLAGS_ADC8; } -static __inline void setadc16(uint16_t a, uint16_t b) +static __inline void +setadc16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b + tempc) & 0xffff; - cpu_state.flags_op = FLAGS_ADC16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xffff; + cpu_state.flags_op = FLAGS_ADC16; } -static __inline void setadc32(uint32_t a, uint32_t b) +static __inline void +setadc32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b + tempc; - cpu_state.flags_op = FLAGS_ADC32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b + tempc; + cpu_state.flags_op = FLAGS_ADC32; } -static __inline void setsbc8(uint8_t a, uint8_t b) +static __inline void +setsbc8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - (b + tempc)) & 0xff; - cpu_state.flags_op = FLAGS_SBC8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xff; + cpu_state.flags_op = FLAGS_SBC8; } -static __inline void setsbc16(uint16_t a, uint16_t b) +static __inline void +setsbc16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - (b + tempc)) & 0xffff; - cpu_state.flags_op = FLAGS_SBC16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xffff; + cpu_state.flags_op = FLAGS_SBC16; } -static __inline void setsbc32(uint32_t a, uint32_t b) +static __inline void +setsbc32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - (b + tempc); - cpu_state.flags_op = FLAGS_SBC32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - (b + tempc); + cpu_state.flags_op = FLAGS_SBC32; } #else -static __inline void setadc8(uint8_t a, uint8_t b) +static __inline void +setadc8(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable8[c&0xFF]; - if (c&0x100) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; + uint16_t c = (uint16_t) a + (uint16_t) b + tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c & 0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } -static __inline void setadc16(uint16_t a, uint16_t b) +static __inline void +setadc16(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable16[c&0xFFFF]; - if (c&0x10000) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; + uint32_t c = (uint32_t) a + (uint32_t) b + tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c & 0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } -static __inline void setadc32(uint32_t a, uint32_t b) +static __inline void +setadc32(uint32_t a, uint32_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); - cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG); - if ((ca) || (c==a && tempc)) cpu_state.flags|=C_FLAG; - if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG; - if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG; + uint32_t c = (uint32_t) a - (((uint32_t) b) + tempc); + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= ((c & 0x80000000) ? N_FLAG : ((!c) ? Z_FLAG : 0)); + cpu_state.flags |= (znptable8[c & 0xFF] & P_FLAG); + if ((c > a) || (c == a && tempc)) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x80000000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - ((b & 0xF) + tempc)) & 0x10) + cpu_state.flags |= A_FLAG; } #endif -extern void cpu_386_flags_extract(); -extern void cpu_386_flags_rebuild(); +extern void cpu_386_flags_extract(void); +extern void cpu_386_flags_rebuild(void); diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index a1ab95125..a5e82d78e 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.h @@ -39,16 +39,14 @@ #ifndef _X86_OPS_H #define _X86_OPS_H - -#define UN_USED(x) (void)(x) - +#define UN_USED(x) (void) (x) typedef int (*OpFn)(uint32_t fetchdat); #ifdef USE_DYNAREC void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, - const OpFn *dynarec_opcodes, - const OpFn *dynarec_opcodes_0f); + const OpFn *dynarec_opcodes, + const OpFn *dynarec_opcodes_0f); extern const OpFn *x86_dynarec_opcodes; extern const OpFn *x86_dynarec_opcodes_0f; @@ -92,10 +90,10 @@ extern const OpFn dynarec_ops_winchip2_0f[1024]; extern const OpFn dynarec_ops_pentium_0f[1024]; extern const OpFn dynarec_ops_pentiummmx_0f[1024]; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) extern const OpFn dynarec_ops_c6x86_0f[1024]; extern const OpFn dynarec_ops_c6x86mx_0f[1024]; -#endif +# endif extern const OpFn dynarec_ops_k6_0f[1024]; extern const OpFn dynarec_ops_k62_0f[1024]; @@ -253,9 +251,9 @@ extern const OpFn ops_REPNE[1024]; extern const OpFn ops_3DNOW[256]; extern const OpFn ops_3DNOWE[256]; -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) #endif /*_X86_OPS_H*/ diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index d24a6cc33..eb7a35ace 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -1,364 +1,385 @@ #include -static int opPREFETCH_a16(uint32_t fetchdat) +static int +opPREFETCH_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + CLOCK_CYCLES(1); + return 0; +} +static int +opPREFETCH_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + + CLOCK_CYCLES(1); + return 0; +} + +static int +opFEMMS(uint32_t fetchdat) +{ + ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); + if (cr0 & 0xc) { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(1); + return 0; +} + +static int +opPAVGUSB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; + + return 0; +} +static int +opPF2ID(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sl[0] = (int32_t) src.f[0]; + cpu_state.MM[cpu_reg].sl[1] = (int32_t) src.f[1]; + + return 0; +} +static int +opPF2IW(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sw[0] = (int32_t) src.f[0]; + cpu_state.MM[cpu_reg].sw[1] = (int32_t) src.f[1]; + + return 0; +} +static int +opPFACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int +opPFNACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int +opPFPNACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int +opPSWAPD(uint32_t fetchdat) +{ + MMX_REG src; + float tempf, tempf2; + + MMX_GETSRC(); + + /* We have to do this in case source and destination overlap. */ + tempf = src.f[0]; + tempf2 = src.f[1]; + cpu_state.MM[cpu_reg].f[1] = tempf; + cpu_state.MM[cpu_reg].f[0] = tempf2; + + return 0; +} +static int +opPFADD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] += src.f[0]; + cpu_state.MM[cpu_reg].f[1] += src.f[1]; + + return 0; +} +static int +opPFCMPEQ(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int +opPFCMPGE(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int +opPFCMPGT(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int +opPFMAX(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int +opPFMIN(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int +opPFMUL(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] *= src.f[0]; + cpu_state.MM[cpu_reg].f[1] *= src.f[1]; + + return 0; +} +static int +opPFRCP(uint32_t fetchdat) +{ + union { + uint32_t i; + float f; + } src; + + if (cpu_mod == 3) { + src.f = cpu_state.MM[cpu_rm].f[0]; CLOCK_CYCLES(1); - return 0; -} -static int opPREFETCH_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } - CLOCK_CYCLES(1); - return 0; -} + cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f; + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; -static int opFEMMS(uint32_t fetchdat) -{ - ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - x87_emms(); - CLOCK_CYCLES(1); - return 0; -} - -static int opPAVGUSB(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; - - return 0; -} -static int opPF2ID(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0]; - cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1]; - - return 0; -} -static int opPF2IW(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = (int32_t)src.f[0]; - cpu_state.MM[cpu_reg].sw[1] = (int32_t)src.f[1]; - - return 0; -} -static int opPFACC(uint32_t fetchdat) -{ - MMX_REG src; - float tempf; - - MMX_GETSRC(); - - tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; - - return 0; -} -static int opPFNACC(uint32_t fetchdat) -{ - MMX_REG src; - float tempf; - - MMX_GETSRC(); - - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; - - return 0; -} -static int opPFPNACC(uint32_t fetchdat) -{ - MMX_REG src; - float tempf; - - MMX_GETSRC(); - - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; - - return 0; -} -static int opPSWAPD(uint32_t fetchdat) -{ - MMX_REG src; - float tempf, tempf2; - - MMX_GETSRC(); - - /* We have to do this in case source and destination overlap. */ - tempf = src.f[0]; - tempf2 = src.f[1]; - cpu_state.MM[cpu_reg].f[1] = tempf; - cpu_state.MM[cpu_reg].f[0] = tempf2; - - return 0; -} -static int opPFADD(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] += src.f[0]; - cpu_state.MM[cpu_reg].f[1] += src.f[1]; - - return 0; -} -static int opPFCMPEQ(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPFCMPGE(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPFCMPGT(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPFMAX(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; - - return 0; -} -static int opPFMIN(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; - - return 0; -} -static int opPFMUL(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] *= src.f[0]; - cpu_state.MM[cpu_reg].f[1] *= src.f[1]; - - return 0; -} -static int opPFRCP(uint32_t fetchdat) -{ - union - { - uint32_t i; - float f; - } src; - - if (cpu_mod == 3) - { - src.f = cpu_state.MM[cpu_rm].f[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_READ(cpu_state.ea_seg); - src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - - cpu_state.MM[cpu_reg].f[0] = 1.0/src.f; - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; - - return 0; + return 0; } /*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/ -static int opPFRCPIT1(uint32_t fetchdat) +static int +opPFRCPIT1(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } -static int opPFRCPIT2(uint32_t fetchdat) +static int +opPFRCPIT2(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } -static int opPFRSQRT(uint32_t fetchdat) +static int +opPFRSQRT(uint32_t fetchdat) { - union - { - uint32_t i; - float f; - } src; + union { + uint32_t i; + float f; + } src; - if (cpu_mod == 3) - { - src.f = cpu_state.MM[cpu_rm].f[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_READ(cpu_state.ea_seg); - src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } + if (cpu_mod == 3) { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } - cpu_state.MM[cpu_reg].f[0] = 1.0/sqrt(src.f); - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f); + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; - return 0; + return 0; } /*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/ -static int opPFRSQIT1(uint32_t fetchdat) +static int +opPFRSQIT1(uint32_t fetchdat) { + MMX_REG src; + + MMX_GETSRC(); + UN_USED(src); + + return 0; +} +static int +opPFSUB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] -= src.f[0]; + cpu_state.MM[cpu_reg].f[1] -= src.f[1]; + + return 0; +} +static int +opPFSUBR(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; + + return 0; +} +static int +opPI2FD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = (float) src.sl[0]; + cpu_state.MM[cpu_reg].f[1] = (float) src.sl[1]; + + return 0; +} +static int +opPI2FW(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = (float) src.sw[0]; + cpu_state.MM[cpu_reg].f[1] = (float) src.sw[1]; + + return 0; +} +static int +opPMULHRW(uint32_t fetchdat) +{ + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = (((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = (((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = (((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = (((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_GETSRC(); - UN_USED(src); - - return 0; -} -static int opPFSUB(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] -= src.f[0]; - cpu_state.MM[cpu_reg].f[1] -= src.f[1]; - - return 0; -} -static int opPFSUBR(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; - - return 0; -} -static int opPI2FD(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0]; - cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1]; - - return 0; -} -static int opPI2FW(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] = (float)src.sw[0]; - cpu_state.MM[cpu_reg].f[1] = (float)src.sw[1]; - - return 0; -} -static int opPMULHRW(uint32_t fetchdat) -{ - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] = (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) (cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) (cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) (cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) (cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(2); + } + return 0; } -const OpFn OP_TABLE(3DNOW)[256] = -{ +const OpFn OP_TABLE(3DNOW)[256] = { + // clang-format off /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL, @@ -379,10 +400,11 @@ const OpFn OP_TABLE(3DNOW)[256] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -const OpFn OP_TABLE(3DNOWE)[256] = -{ +const OpFn OP_TABLE(3DNOWE)[256] = { + // clang-format off /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FW, opPI2FD, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2IW, opPF2ID, ILLEGAL, ILLEGAL, @@ -403,31 +425,36 @@ const OpFn OP_TABLE(3DNOWE)[256] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on }; -static int op3DNOW_a16(uint32_t fetchdat) +static int +op3DNOW_a16(uint32_t fetchdat) { - uint8_t opcode; + uint8_t opcode; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - opcode = fastreadb(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetch_ea_16(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - return x86_opcodes_3DNOW[opcode](0); + return x86_opcodes_3DNOW[opcode](0); } -static int op3DNOW_a32(uint32_t fetchdat) +static int +op3DNOW_a32(uint32_t fetchdat) { - uint8_t opcode; + uint8_t opcode; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - opcode = fastreadb(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetch_ea_32(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - return x86_opcodes_3DNOW[opcode](0); + return x86_opcodes_3DNOW[opcode](0); } diff --git a/src/cpu/x86_ops_amd.h b/src/cpu/x86_ops_amd.h index a378b9fe9..9e6bcce55 100644 --- a/src/cpu/x86_ops_amd.h +++ b/src/cpu/x86_ops_amd.h @@ -1,17 +1,17 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * AMD SYSCALL and SYSRET CPU Instructions. + * AMD SYSCALL and SYSRET CPU Instructions. * * * - * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. + * Authors: Miran Grca, + * Copyright 2016-2018 Miran Grca. */ static int opSYSCALL(uint32_t fetchdat) @@ -23,16 +23,15 @@ opSYSCALL(uint32_t fetchdat) ret = syscall_op(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; } - static int opSYSRET(uint32_t fetchdat) { @@ -43,10 +42,10 @@ opSYSRET(uint32_t fetchdat) ret = sysret(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; diff --git a/src/cpu/x86_ops_arith.h b/src/cpu/x86_ops_arith.h index b56abb26a..41c655d09 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu/x86_ops_arith.h @@ -1,827 +1,1012 @@ -#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ - static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _b_rm_a16(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _b_rm_a32(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _w_rm_a16(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _w_rm_a32(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _l_rm_a16(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _l_rm_a32(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _AL_imm(uint32_t fetchdat) \ - { \ - uint8_t dst = AL; \ - uint8_t src = getbytef(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 8 flagops; \ - AL = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _AX_imm(uint32_t fetchdat) \ - { \ - uint16_t dst = AX; \ - uint16_t src = getwordf(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 16 flagops; \ - AX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _EAX_imm(uint32_t fetchdat) \ - { \ - uint32_t dst = EAX; \ - uint32_t src = getlong(); if (cpu_state.abrt) return 1; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 32 flagops; \ - EAX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); \ - return 0; \ - } +#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ + static int op##name##_b_rmw_a16(uint32_t fetchdat) \ + { \ + uint8_t dst; \ + uint8_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + dst = getr8(cpu_rm); \ + src = getr8(cpu_reg); \ + setflags##8 flagops; \ + setr8(cpu_rm, operation); \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + src = getr8(cpu_reg); \ + seteab(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_mr, 2, rmdat, 1, 0, 1, 0, 0); \ + } \ + return 0; \ + } \ + static int op##name##_b_rmw_a32(uint32_t fetchdat) \ + { \ + uint8_t dst; \ + uint8_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + dst = getr8(cpu_rm); \ + src = getr8(cpu_reg); \ + setflags##8 flagops; \ + setr8(cpu_rm, operation); \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + src = getr8(cpu_reg); \ + seteab(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_mr, 2, rmdat, 1, 0, 1, 0, 1); \ + } \ + return 0; \ + } \ + \ + static int op##name##_w_rmw_a16(uint32_t fetchdat) \ + { \ + uint16_t dst; \ + uint16_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].w; \ + src = cpu_state.regs[cpu_reg].w; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_rm].w = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].w; \ + seteaw(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 1, 0, 1, 0, 0); \ + } \ + return 0; \ + } \ + static int op##name##_w_rmw_a32(uint32_t fetchdat) \ + { \ + uint16_t dst; \ + uint16_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].w; \ + src = cpu_state.regs[cpu_reg].w; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_rm].w = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].w; \ + seteaw(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 1, 0, 1, 0, 1); \ + } \ + return 0; \ + } \ + \ + static int op##name##_l_rmw_a16(uint32_t fetchdat) \ + { \ + uint32_t dst; \ + uint32_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].l; \ + src = cpu_state.regs[cpu_reg].l; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_rm].l = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].l; \ + seteal(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 1, 0, 1, 0); \ + } \ + return 0; \ + } \ + static int op##name##_l_rmw_a32(uint32_t fetchdat) \ + { \ + uint32_t dst; \ + uint32_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].l; \ + src = cpu_state.regs[cpu_reg].l; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_rm].l = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].l; \ + seteal(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 1, 0, 1, 1); \ + } \ + return 0; \ + } \ + \ + static int op##name##_b_rm_a16(uint32_t fetchdat) \ + { \ + uint8_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = getr8(cpu_reg); \ + src = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + setr8(cpu_reg, operation); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); \ + return 0; \ + } \ + static int op##name##_b_rm_a32(uint32_t fetchdat) \ + { \ + uint8_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = getr8(cpu_reg); \ + src = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + setr8(cpu_reg, operation); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); \ + return 0; \ + } \ + \ + static int op##name##_w_rm_a16(uint32_t fetchdat) \ + { \ + uint16_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].w; \ + src = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_reg].w = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); \ + return 0; \ + } \ + static int op##name##_w_rm_a32(uint32_t fetchdat) \ + { \ + uint16_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].w; \ + src = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_reg].w = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); \ + return 0; \ + } \ + \ + static int op##name##_l_rm_a16(uint32_t fetchdat) \ + { \ + uint32_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].l; \ + src = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_reg].l = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); \ + return 0; \ + } \ + static int op##name##_l_rm_a32(uint32_t fetchdat) \ + { \ + uint32_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].l; \ + src = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_reg].l = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); \ + return 0; \ + } \ + \ + static int op##name##_AL_imm(uint32_t fetchdat) \ + { \ + uint8_t dst = AL; \ + uint8_t src = getbytef(); \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + setflags##8 flagops; \ + AL = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int op##name##_AX_imm(uint32_t fetchdat) \ + { \ + uint16_t dst = AX; \ + uint16_t src = getwordf(); \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + setflags##16 flagops; \ + AX = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int op##name##_EAX_imm(uint32_t fetchdat) \ + { \ + uint32_t dst = EAX; \ + uint32_t src = getlong(); \ + if (cpu_state.abrt) \ + return 1; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + setflags##32 flagops; \ + EAX = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } -OP_ARITH(ADD, dst + src, setadd, (dst, src), 0) -OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1) -OP_ARITH(SUB, dst - src, setsub, (dst, src), 0) +OP_ARITH(ADD, dst + src, setadd, (dst, src), 0) +OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1) +OP_ARITH(SUB, dst - src, setsub, (dst, src), 0) OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src), 1) -OP_ARITH(OR, dst | src, setznp, (dst | src), 0) -OP_ARITH(AND, dst & src, setznp, (dst & src), 0) -OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0) +OP_ARITH(OR, dst | src, setznp, (dst | src), 0) +OP_ARITH(AND, dst &src, setznp, (dst & src), 0) +OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0) -static int opCMP_b_rmw_a16(uint32_t fetchdat) +static int +opCMP_b_rmw_a16(uint32_t fetchdat) { - uint8_t dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint8_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(dst, getr8(cpu_reg)); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_b_rmw_a32(uint32_t fetchdat) +static int +opCMP_b_rmw_a32(uint32_t fetchdat) { - uint8_t dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint8_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(dst, getr8(cpu_reg)); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_w_rmw_a16(uint32_t fetchdat) +static int +opCMP_w_rmw_a16(uint32_t fetchdat) { - uint16_t dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint16_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(dst, cpu_state.regs[cpu_reg].w); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_w_rmw_a32(uint32_t fetchdat) +static int +opCMP_w_rmw_a32(uint32_t fetchdat) { - uint16_t dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint16_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(dst, cpu_state.regs[cpu_reg].w); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_l_rmw_a16(uint32_t fetchdat) +static int +opCMP_l_rmw_a16(uint32_t fetchdat) { - uint32_t dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; + uint32_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(dst, cpu_state.regs[cpu_reg].l); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; } -static int opCMP_l_rmw_a32(uint32_t fetchdat) +static int +opCMP_l_rmw_a32(uint32_t fetchdat) { - uint32_t dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; + uint32_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(dst, cpu_state.regs[cpu_reg].l); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; } -static int opCMP_b_rm_a16(uint32_t fetchdat) +static int +opCMP_b_rm_a16(uint32_t fetchdat) { - uint8_t src; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint8_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(getr8(cpu_reg), src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_b_rm_a32(uint32_t fetchdat) +static int +opCMP_b_rm_a32(uint32_t fetchdat) { - uint8_t src; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint8_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(getr8(cpu_reg), src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_w_rm_a16(uint32_t fetchdat) +static int +opCMP_w_rm_a16(uint32_t fetchdat) { - uint16_t src; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint16_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(cpu_state.regs[cpu_reg].w, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_w_rm_a32(uint32_t fetchdat) +static int +opCMP_w_rm_a32(uint32_t fetchdat) { - uint16_t src; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint16_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(cpu_state.regs[cpu_reg].w, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_l_rm_a16(uint32_t fetchdat) +static int +opCMP_l_rm_a16(uint32_t fetchdat) { - uint32_t src; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; + uint32_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(cpu_state.regs[cpu_reg].l, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; } -static int opCMP_l_rm_a32(uint32_t fetchdat) +static int +opCMP_l_rm_a32(uint32_t fetchdat) { - uint32_t src; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; + uint32_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(cpu_state.regs[cpu_reg].l, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; } -static int opCMP_AL_imm(uint32_t fetchdat) +static int +opCMP_AL_imm(uint32_t fetchdat) { - uint8_t src = getbytef(); - setsub8(AL, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + uint8_t src = getbytef(); + setsub8(AL, src); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCMP_AX_imm(uint32_t fetchdat) +static int +opCMP_AX_imm(uint32_t fetchdat) { - uint16_t src = getwordf(); - setsub16(AX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + uint16_t src = getwordf(); + setsub16(AX, src); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCMP_EAX_imm(uint32_t fetchdat) +static int +opCMP_EAX_imm(uint32_t fetchdat) { - uint32_t src = getlong(); if (cpu_state.abrt) return 1; - setsub32(EAX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t src = getlong(); + if (cpu_state.abrt) + return 1; + setsub32(EAX, src); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opTEST_b_a16(uint32_t fetchdat) +static int +opTEST_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint8_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + temp2 = getr8(cpu_reg); + setznp8(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opTEST_b_a32(uint32_t fetchdat) +static int +opTEST_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint8_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + temp2 = getr8(cpu_reg); + setznp8(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opTEST_w_a16(uint32_t fetchdat) +static int +opTEST_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint16_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].w; + setznp16(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opTEST_w_a32(uint32_t fetchdat) +static int +opTEST_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint16_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].w; + setznp16(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opTEST_l_a16(uint32_t fetchdat) +static int +opTEST_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; + uint32_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].l; + setznp32(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; } -static int opTEST_l_a32(uint32_t fetchdat) +static int +opTEST_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; + uint32_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].l; + setznp32(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; } -static int opTEST_AL(uint32_t fetchdat) +static int +opTEST_AL(uint32_t fetchdat) { - uint8_t temp = getbytef(); - setznp8(AL & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + uint8_t temp = getbytef(); + setznp8(AL & temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opTEST_AX(uint32_t fetchdat) +static int +opTEST_AX(uint32_t fetchdat) { - uint16_t temp = getwordf(); - setznp16(AX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = getwordf(); + setznp16(AX & temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opTEST_EAX(uint32_t fetchdat) +static int +opTEST_EAX(uint32_t fetchdat) { - uint32_t temp = getlong(); if (cpu_state.abrt) return 1; - setznp32(EAX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = getlong(); + if (cpu_state.abrt) + return 1; + setznp32(EAX & temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } +#define ARITH_MULTI(ea_width, flag_width) \ + dst = getea##ea_width(); \ + if (cpu_state.abrt) \ + return 1; \ + switch (rmdat & 0x38) { \ + case 0x00: /*ADD ea, #*/ \ + setea##ea_width(dst + src); \ + if (cpu_state.abrt) \ + return 1; \ + setadd##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x08: /*OR ea, #*/ \ + dst |= src; \ + setea##ea_width(dst); \ + if (cpu_state.abrt) \ + return 1; \ + setznp##flag_width(dst); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x10: /*ADC ea, #*/ \ + tempc = CF_SET() ? 1 : 0; \ + setea##ea_width(dst + src + tempc); \ + if (cpu_state.abrt) \ + return 1; \ + setadc##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x18: /*SBB ea, #*/ \ + tempc = CF_SET() ? 1 : 0; \ + setea##ea_width(dst - (src + tempc)); \ + if (cpu_state.abrt) \ + return 1; \ + setsbc##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x20: /*AND ea, #*/ \ + dst &= src; \ + setea##ea_width(dst); \ + if (cpu_state.abrt) \ + return 1; \ + setznp##flag_width(dst); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x28: /*SUB ea, #*/ \ + setea##ea_width(dst - src); \ + if (cpu_state.abrt) \ + return 1; \ + setsub##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x30: /*XOR ea, #*/ \ + dst ^= src; \ + setea##ea_width(dst); \ + if (cpu_state.abrt) \ + return 1; \ + setznp##flag_width(dst); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x38: /*CMP ea, #*/ \ + setsub##flag_width(dst, src); \ + if (is486) { \ + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \ + } else { \ + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \ + } \ + break; \ + } -#define ARITH_MULTI(ea_width, flag_width) \ - dst = getea ## ea_width(); if (cpu_state.abrt) return 1; \ - switch (rmdat&0x38) \ - { \ - case 0x00: /*ADD ea, #*/ \ - setea ## ea_width(dst + src); if (cpu_state.abrt) return 1; \ - setadd ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x08: /*OR ea, #*/ \ - dst |= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x10: /*ADC ea, #*/ \ - tempc = CF_SET() ? 1 : 0; \ - setea ## ea_width(dst + src + tempc); if (cpu_state.abrt) return 1; \ - setadc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x18: /*SBB ea, #*/ \ - tempc = CF_SET() ? 1 : 0; \ - setea ## ea_width(dst - (src + tempc)); if (cpu_state.abrt) return 1; \ - setsbc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x20: /*AND ea, #*/ \ - dst &= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x28: /*SUB ea, #*/ \ - setea ## ea_width(dst - src); if (cpu_state.abrt) return 1; \ - setsub ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x30: /*XOR ea, #*/ \ - dst ^= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x38: /*CMP ea, #*/ \ - setsub ## flag_width(dst, src); \ - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } \ - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); } \ - break; \ - } - - -static int op80_a16(uint32_t fetchdat) +static int +op80_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(b, 8); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + } - return 0; + return 0; } -static int op80_a32(uint32_t fetchdat) +static int +op80_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(b, 8); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + } - return 0; + return 0; } -static int op81_w_a16(uint32_t fetchdat) +static int +op81_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getword(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + } - return 0; + return 0; } -static int op81_w_a32(uint32_t fetchdat) +static int +op81_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getword(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + } - return 0; + return 0; } -static int op81_l_a16(uint32_t fetchdat) +static int +op81_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + } - return 0; + return 0; } -static int op81_l_a32(uint32_t fetchdat) +static int +op81_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + } - return 0; + return 0; } -static int op83_w_a16(uint32_t fetchdat) +static int +op83_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xff00; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + } - return 0; + return 0; } -static int op83_w_a32(uint32_t fetchdat) +static int +op83_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xff00; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + } - return 0; + return 0; } -static int op83_l_a16(uint32_t fetchdat) +static int +op83_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xffffff00; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + } - return 0; + return 0; } -static int op83_l_a32(uint32_t fetchdat) +static int +op83_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xffffff00; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + } - return 0; + return 0; } diff --git a/src/cpu/x86_ops_atomic.h b/src/cpu/x86_ops_atomic.h index 13b672e31..7c7b409d2 100644 --- a/src/cpu/x86_ops_atomic.h +++ b/src/cpu/x86_ops_atomic.h @@ -1,227 +1,295 @@ -static int opCMPXCHG_b_a16(uint32_t fetchdat) +static int +opCMPXCHG_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - if (AL == temp) seteab(getr8(cpu_reg)); - else AL = temp; - if (cpu_state.abrt) return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint8_t temp, temp2 = AL; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + if (AL == temp) + seteab(getr8(cpu_reg)); + else + AL = temp; + if (cpu_state.abrt) + return 1; + setsub8(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_b_a32(uint32_t fetchdat) +static int +opCMPXCHG_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - if (AL == temp) seteab(getr8(cpu_reg)); - else AL = temp; - if (cpu_state.abrt) return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint8_t temp, temp2 = AL; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + if (AL == temp) + seteab(getr8(cpu_reg)); + else + AL = temp; + if (cpu_state.abrt) + return 1; + setsub8(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_w_a16(uint32_t fetchdat) +static int +opCMPXCHG_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); - else AX = temp; - if (cpu_state.abrt) return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint16_t temp, temp2 = AX; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (AX == temp) + seteaw(cpu_state.regs[cpu_reg].w); + else + AX = temp; + if (cpu_state.abrt) + return 1; + setsub16(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_w_a32(uint32_t fetchdat) +static int +opCMPXCHG_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); - else AX = temp; - if (cpu_state.abrt) return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint16_t temp, temp2 = AX; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (AX == temp) + seteaw(cpu_state.regs[cpu_reg].w); + else + AX = temp; + if (cpu_state.abrt) + return 1; + setsub16(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_l_a16(uint32_t fetchdat) +static int +opCMPXCHG_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); - else EAX = temp; - if (cpu_state.abrt) return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint32_t temp, temp2 = EAX; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (EAX == temp) + seteal(cpu_state.regs[cpu_reg].l); + else + EAX = temp; + if (cpu_state.abrt) + return 1; + setsub32(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_l_a32(uint32_t fetchdat) +static int +opCMPXCHG_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); - else EAX = temp; - if (cpu_state.abrt) return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint32_t temp, temp2 = EAX; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (EAX == temp) + seteal(cpu_state.regs[cpu_reg].l); + else + EAX = temp; + if (cpu_state.abrt) + return 1; + setsub32(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG8B_a16(uint32_t fetchdat) +static int +opCMPXCHG8B_a16(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - if (EAX == temp && EDX == temp_hi) - { - seteal(EBX); - writememl(easeg, cpu_state.eaaddr+4, ECX); - } - else - { - EAX = temp; - EDX = temp_hi; - } - if (cpu_state.abrt) return 0; - flags_rebuild(); - if (temp == temp2 && temp_hi == temp2_hi) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; + uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) return 0; + if (EAX == temp && EDX == temp_hi) { + seteal(EBX); + writememl(easeg, cpu_state.eaaddr + 4, ECX); + } else { + EAX = temp; + EDX = temp_hi; + } + if (cpu_state.abrt) + return 0; + flags_rebuild(); + if (temp == temp2 && temp_hi == temp2_hi) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; + return 0; } -static int opCMPXCHG8B_a32(uint32_t fetchdat) +static int +opCMPXCHG8B_a32(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - if (EAX == temp && EDX == temp_hi) - { - seteal(EBX); - writememl(easeg, cpu_state.eaaddr+4, ECX); - } - else - { - EAX = temp; - EDX = temp_hi; - } - if (cpu_state.abrt) return 0; - flags_rebuild(); - if (temp == temp2 && temp_hi == temp2_hi) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; + uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) return 0; + if (EAX == temp && EDX == temp_hi) { + seteal(EBX); + writememl(easeg, cpu_state.eaaddr + 4, ECX); + } else { + EAX = temp; + EDX = temp_hi; + } + if (cpu_state.abrt) + return 0; + flags_rebuild(); + if (temp == temp2 && temp_hi == temp2_hi) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; + return 0; } /* dest = eab, src = r8 */ -static int opXADD_b_a16(uint32_t fetchdat) +static int +opXADD_b_a16(uint32_t fetchdat) { - uint8_t temp; - uint8_t src, dest; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getr8(cpu_reg); - dest = geteab(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteab(temp); if (cpu_state.abrt) return 1; - setadd8(src, dest); - setr8(cpu_reg, dest); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint8_t temp; + uint8_t src, dest; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getr8(cpu_reg); + dest = geteab(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteab(temp); + if (cpu_state.abrt) + return 1; + setadd8(src, dest); + setr8(cpu_reg, dest); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_b_a32(uint32_t fetchdat) +static int +opXADD_b_a32(uint32_t fetchdat) { - uint8_t temp; - uint8_t src, dest; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getr8(cpu_reg); - dest = geteab(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteab(temp); if (cpu_state.abrt) return 1; - setadd8(src, dest); - setr8(cpu_reg, dest); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint8_t temp; + uint8_t src, dest; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getr8(cpu_reg); + dest = geteab(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteab(temp); + if (cpu_state.abrt) + return 1; + setadd8(src, dest); + setr8(cpu_reg, dest); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_w_a16(uint32_t fetchdat) +static int +opXADD_w_a16(uint32_t fetchdat) { - uint16_t temp; - uint16_t src, dest; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].w; - dest = geteaw(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteaw(temp); if (cpu_state.abrt) return 1; - setadd16(src, dest); - cpu_state.regs[cpu_reg].w = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint16_t temp; + uint16_t src, dest; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].w; + dest = geteaw(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteaw(temp); + if (cpu_state.abrt) + return 1; + setadd16(src, dest); + cpu_state.regs[cpu_reg].w = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_w_a32(uint32_t fetchdat) +static int +opXADD_w_a32(uint32_t fetchdat) { - uint16_t temp; - uint16_t src, dest; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].w; - dest = geteaw(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteaw(temp); if (cpu_state.abrt) return 1; - setadd16(src, dest); - cpu_state.regs[cpu_reg].w = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint16_t temp; + uint16_t src, dest; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].w; + dest = geteaw(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteaw(temp); + if (cpu_state.abrt) + return 1; + setadd16(src, dest); + cpu_state.regs[cpu_reg].w = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_l_a16(uint32_t fetchdat) +static int +opXADD_l_a16(uint32_t fetchdat) { - uint32_t temp; - uint32_t src, dest; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].l; - dest = geteal(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteal(temp); if (cpu_state.abrt) return 1; - setadd32(src, dest); - cpu_state.regs[cpu_reg].l = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint32_t temp; + uint32_t src, dest; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].l; + dest = geteal(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteal(temp); + if (cpu_state.abrt) + return 1; + setadd32(src, dest); + cpu_state.regs[cpu_reg].l = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_l_a32(uint32_t fetchdat) +static int +opXADD_l_a32(uint32_t fetchdat) { - uint32_t temp; - uint32_t src, dest; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].l; - dest = geteal(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteal(temp); if (cpu_state.abrt) return 1; - setadd32(src, dest); - cpu_state.regs[cpu_reg].l = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint32_t temp; + uint32_t src, dest; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].l; + dest = geteal(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteal(temp); + if (cpu_state.abrt) + return 1; + setadd32(src, dest); + cpu_state.regs[cpu_reg].l = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index 385d63cd7..d3ff97ead 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -1,129 +1,130 @@ -static int opAAA(uint32_t fetchdat) +static int +opAAA(uint32_t fetchdat) { - flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) - { - /* On 286, it's indeed AX - behavior difference from 808x. */ - AX += 6; - AH++; - cpu_state.flags |= (A_FLAG | C_FLAG); - } - else - cpu_state.flags &= ~(A_FLAG | C_FLAG); - AL &= 0xF; - CLOCK_CYCLES(is486 ? 3 : 4); - PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + /* On 286, it's indeed AX - behavior difference from 808x. */ + AX += 6; + AH++; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.flags &= ~(A_FLAG | C_FLAG); + AL &= 0xF; + CLOCK_CYCLES(is486 ? 3 : 4); + PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opAAD(uint32_t fetchdat) +static int +opAAD(uint32_t fetchdat) { - int base = getbytef(); - if (!cpu_isintel) base = 10; - AL = (AH * base) + AL; - AH = 0; - setznp16(AX); - CLOCK_CYCLES((is486) ? 14 : 19); - PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0,0,0,0, 0); - return 0; + int base = getbytef(); + if (!cpu_isintel) + base = 10; + AL = (AH * base) + AL; + AH = 0; + setznp16(AX); + CLOCK_CYCLES((is486) ? 14 : 19); + PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opAAM(uint32_t fetchdat) +static int +opAAM(uint32_t fetchdat) { - int base = getbytef(); - if (!base || !cpu_isintel) base = 10; - AH = AL / base; - AL %= base; - setznp16(AX); - CLOCK_CYCLES((is486) ? 15 : 17); - PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0,0,0,0, 0); - return 0; + int base = getbytef(); + if (!base || !cpu_isintel) + base = 10; + AH = AL / base; + AL %= base; + setznp16(AX); + CLOCK_CYCLES((is486) ? 15 : 17); + PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opAAS(uint32_t fetchdat) +static int +opAAS(uint32_t fetchdat) { - flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) - { - /* On 286, it's indeed AX - behavior difference from 808x. */ - AX -= 6; - AH--; - cpu_state.flags |= (A_FLAG | C_FLAG); - } - else - cpu_state.flags &= ~(A_FLAG | C_FLAG); - AL &= 0xF; - CLOCK_CYCLES(is486 ? 3 : 4); - PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + /* On 286, it's indeed AX - behavior difference from 808x. */ + AX -= 6; + AH--; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.flags &= ~(A_FLAG | C_FLAG); + AL &= 0xF; + CLOCK_CYCLES(is486 ? 3 : 4); + PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opDAA(uint32_t fetchdat) +static int +opDAA(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw, old_AL, old_CF; - flags_rebuild(); - old_AL = AL; - old_CF = cpu_state.flags & C_FLAG; - cpu_state.flags &= ~C_FLAG; + flags_rebuild(); + old_AL = AL; + old_CF = cpu_state.flags & C_FLAG; + cpu_state.flags &= ~C_FLAG; - if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { - int tempi = ((uint16_t)AL) + 6; - AL += 6; - if (old_CF || (tempi & 0x100)) - cpu_state.flags |= C_FLAG; - cpu_state.flags |= A_FLAG; - } else - cpu_state.flags &= ~A_FLAG; + if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { + int tempi = ((uint16_t) AL) + 6; + AL += 6; + if (old_CF || (tempi & 0x100)) + cpu_state.flags |= C_FLAG; + cpu_state.flags |= A_FLAG; + } else + cpu_state.flags &= ~A_FLAG; - if ((old_AL > 0x99) || old_CF) - { - AL += 0x60; - cpu_state.flags |= C_FLAG; - } else - cpu_state.flags &= ~C_FLAG; + if ((old_AL > 0x99) || old_CF) { + AL += 0x60; + cpu_state.flags |= C_FLAG; + } else + cpu_state.flags &= ~C_FLAG; - tempw = cpu_state.flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); + setznp8(AL); + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); - return 0; + return 0; } -static int opDAS(uint32_t fetchdat) +static int +opDAS(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw, old_AL, old_CF; - flags_rebuild(); - old_AL = AL; - old_CF = cpu_state.flags & C_FLAG; - cpu_state.flags &= ~C_FLAG; + flags_rebuild(); + old_AL = AL; + old_CF = cpu_state.flags & C_FLAG; + cpu_state.flags &= ~C_FLAG; - if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) - { - int tempi = ((uint16_t)AL) - 6; - AL -= 6; - if (old_CF || (tempi & 0x100)) - cpu_state.flags |= C_FLAG; - cpu_state.flags |= A_FLAG; - } else - cpu_state.flags &= ~A_FLAG; + if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { + int tempi = ((uint16_t) AL) - 6; + AL -= 6; + if (old_CF || (tempi & 0x100)) + cpu_state.flags |= C_FLAG; + cpu_state.flags |= A_FLAG; + } else + cpu_state.flags &= ~A_FLAG; - if ((old_AL > 0x99) || old_CF) - { - AL -= 0x60; - cpu_state.flags |= C_FLAG; - } + if ((old_AL > 0x99) || old_CF) { + AL -= 0x60; + cpu_state.flags |= C_FLAG; + } - tempw = cpu_state.flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); + setznp8(AL); + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); - return 0; + return 0; } diff --git a/src/cpu/x86_ops_bit.h b/src/cpu/x86_ops_bit.h index 4fc8ac0f7..8514e8e1c 100644 --- a/src/cpu/x86_ops_bit.h +++ b/src/cpu/x86_ops_bit.h @@ -1,328 +1,411 @@ -static int opBT_w_r_a16(uint32_t fetchdat) +static int +opBT_w_r_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; - temp = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); + eal_r = 0; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opBT_w_r_a32(uint32_t fetchdat) +static int +opBT_w_r_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; - temp = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); + eal_r = 0; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opBT_l_r_a16(uint32_t fetchdat) +static int +opBT_l_r_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; - temp = geteal(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); + eal_r = 0; + temp = geteal(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opBT_l_r_a32(uint32_t fetchdat) +static int +opBT_l_r_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; - temp = geteal(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); + eal_r = 0; + temp = geteal(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 1); + return 0; } -#define opBT(name, operation) \ - static int opBT ## name ## _w_r_a16(uint32_t fetchdat) \ - { \ - int tempc; \ - uint16_t temp; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 0); \ - return 0; \ - } \ - static int opBT ## name ## _w_r_a32(uint32_t fetchdat) \ - { \ - int tempc; \ - uint16_t temp; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 1); \ - return 0; \ - } \ - static int opBT ## name ## _l_r_a16(uint32_t fetchdat) \ - { \ - int tempc; \ - uint32_t temp; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 0); \ - return 0; \ - } \ - static int opBT ## name ## _l_r_a32(uint32_t fetchdat) \ - { \ - int tempc; \ - uint32_t temp; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 1); \ - return 0; \ - } +#define opBT(name, operation) \ + static int opBT##name##_w_r_a16(uint32_t fetchdat) \ + { \ + int tempc; \ + uint16_t temp; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \ + eal_r = eal_w = 0; \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 0); \ + return 0; \ + } \ + static int opBT##name##_w_r_a32(uint32_t fetchdat) \ + { \ + int tempc; \ + uint16_t temp; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \ + eal_r = eal_w = 0; \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 1); \ + return 0; \ + } \ + static int opBT##name##_l_r_a16(uint32_t fetchdat) \ + { \ + int tempc; \ + uint32_t temp; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \ + eal_r = eal_w = 0; \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 0); \ + return 0; \ + } \ + static int opBT##name##_l_r_a32(uint32_t fetchdat) \ + { \ + int tempc; \ + uint32_t temp; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \ + eal_r = eal_w = 0; \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 1); \ + return 0; \ + } opBT(C, ^=) -opBT(R, &=~) -opBT(S, |=) + opBT(R, &= ~) + opBT(S, |=) -static int opBA_w_a16(uint32_t fetchdat) + static int opBA_w_a16(uint32_t fetchdat) { - int tempc, count; - uint16_t temp; + int tempc, count; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteaw(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteaw(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opBA_w_a32(uint32_t fetchdat) +static int +opBA_w_a32(uint32_t fetchdat) { - int tempc, count; - uint16_t temp; + int tempc, count; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteaw(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteaw(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opBA_l_a16(uint32_t fetchdat) +static int +opBA_l_a16(uint32_t fetchdat) { - int tempc, count; - uint32_t temp; + int tempc, count; + uint32_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteal(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteal(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + return 0; } -static int opBA_l_a32(uint32_t fetchdat) +static int +opBA_l_a32(uint32_t fetchdat) { - int tempc, count; - uint32_t temp; + int tempc, count; + uint32_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteal(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteal(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + return 0; } diff --git a/src/cpu/x86_ops_bitscan.h b/src/cpu/x86_ops_bitscan.h index af87a545d..358131c1e 100644 --- a/src/cpu/x86_ops_bitscan.h +++ b/src/cpu/x86_ops_bitscan.h @@ -1,211 +1,227 @@ #ifdef IS_DYNAREC -#define BS_common(start, end, dir, dest, time) \ - flags_rebuild(); \ - if (temp) \ - { \ - int c; \ - cpu_state.flags &= ~Z_FLAG; \ - for (c = start; c != end; c += dir) \ - { \ - CLOCK_CYCLES(time); \ - if (temp & (1 << c)) \ - { \ - dest = c; \ - break; \ - } \ - } \ - } \ - else \ - cpu_state.flags |= Z_FLAG; +# define BS_common(start, end, dir, dest, time) \ + flags_rebuild(); \ + if (temp) { \ + int c; \ + cpu_state.flags &= ~Z_FLAG; \ + for (c = start; c != end; c += dir) { \ + CLOCK_CYCLES(time); \ + if (temp & (1 << c)) { \ + dest = c; \ + break; \ + } \ + } \ + } else \ + cpu_state.flags |= Z_FLAG; #else -#define BS_common(start, end, dir, dest, time) \ - flags_rebuild(); \ - instr_cycles = 0; \ - if (temp) \ - { \ - int c; \ - cpu_state.flags &= ~Z_FLAG; \ - for (c = start; c != end; c += dir) \ - { \ - CLOCK_CYCLES(time); \ - instr_cycles += time; \ - if (temp & (1 << c)) \ - { \ - dest = c; \ - break; \ - } \ - } \ - } \ - else \ - cpu_state.flags |= Z_FLAG; +# define BS_common(start, end, dir, dest, time) \ + flags_rebuild(); \ + instr_cycles = 0; \ + if (temp) { \ + int c; \ + cpu_state.flags &= ~Z_FLAG; \ + for (c = start; c != end; c += dir) { \ + CLOCK_CYCLES(time); \ + instr_cycles += time; \ + if (temp & (1 << c)) { \ + dest = c; \ + break; \ + } \ + } \ + } else \ + cpu_state.flags |= Z_FLAG; #endif -static int opBSF_w_a16(uint32_t fetchdat) +static int +opBSF_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); + BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSF_w_a32(uint32_t fetchdat) +static int +opBSF_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); + BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); #endif - return 0; + return 0; } -static int opBSF_l_a16(uint32_t fetchdat) +static int +opBSF_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); + BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSF_l_a32(uint32_t fetchdat) +static int +opBSF_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); + BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); #endif - return 0; + return 0; } -static int opBSR_w_a16(uint32_t fetchdat) +static int +opBSR_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); + BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSR_w_a32(uint32_t fetchdat) +static int +opBSR_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); + BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); #endif - return 0; + return 0; } -static int opBSR_l_a16(uint32_t fetchdat) +static int +opBSR_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); + BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSR_l_a32(uint32_t fetchdat) +static int +opBSR_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); + BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); #endif - return 0; + return 0; } diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index ecd50f107..88899cef8 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -1,627 +1,879 @@ #ifdef USE_NEW_DYNAREC -#define CALL_FAR_w(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg, old_pc); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate32) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ +# define CALL_FAR_w(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg, old_pc); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate32) { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ } -#define CALL_FAR_l(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg, old_pc); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate16) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ +# define CALL_FAR_l(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg, old_pc); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate16) { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ } #else -#define CALL_FAR_w(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate32) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ +# define CALL_FAR_w(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate32) { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ } -#define CALL_FAR_l(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate16) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ +# define CALL_FAR_l(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate16) { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ } #endif - -static int opCALL_far_w(uint32_t fetchdat) +static int +opCALL_far_w(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint16_t new_cs, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint32_t old_cs, old_pc; + uint16_t new_cs, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - new_pc = getwordf(); - new_cs = getword(); if (cpu_state.abrt) return 1; + new_pc = getwordf(); + new_cs = getword(); + if (cpu_state.abrt) + return 1; - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 5, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 5, -1, 0, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); - return 0; + return 0; } -static int opCALL_far_l(uint32_t fetchdat) +static int +opCALL_far_l(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint32_t new_cs, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint32_t old_cs, old_pc; + uint32_t new_cs, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - new_pc = getlong(); - new_cs = getword(); if (cpu_state.abrt) return 1; + new_pc = getlong(); + new_cs = getword(); + if (cpu_state.abrt) + return 1; - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 7, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); + CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 7, -1, 0, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); - return 0; + return 0; } - -static int opFF_w_a16(uint32_t fetchdat) +static int +opFF_w_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp + 1); if (cpu_state.abrt) return 1; - setadd16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x08: /*DEC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp - 1); if (cpu_state.abrt) return 1; - setsub16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp + 1); + if (cpu_state.abrt) + return 1; + setadd16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x08: /*DEC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp - 1); + if (cpu_state.abrt) + return 1; + setsub16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(cpu_state.pc); + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); + if (cpu_state.abrt) + return 1; - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(temp); + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 0); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } -static int opFF_w_a32(uint32_t fetchdat) +static int +opFF_w_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp + 1); if (cpu_state.abrt) return 1; - setadd16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x08: /*DEC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp - 1); if (cpu_state.abrt) return 1; - setsub16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp + 1); + if (cpu_state.abrt) + return 1; + setadd16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x08: /*DEC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp - 1); + if (cpu_state.abrt) + return 1; + setsub16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(cpu_state.pc); + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); + if (cpu_state.abrt) + return 1; - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 1); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,0,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 1); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 0, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(temp); + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 1); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } -static int opFF_l_a16(uint32_t fetchdat) +static int +opFF_l_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp + 1); if (cpu_state.abrt) return 1; - setadd32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x08: /*DEC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp - 1); if (cpu_state.abrt) return 1; - setsub32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp + 1); + if (cpu_state.abrt) + return 1; + setadd32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x08: /*DEC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp - 1); + if (cpu_state.abrt) + return 1; + setsub32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(cpu_state.pc); + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 0); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); + if (cpu_state.abrt) + return 1; - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 0,1,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } + CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(temp); + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 0); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } -static int opFF_l_a32(uint32_t fetchdat) +static int +opFF_l_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp + 1); if (cpu_state.abrt) return 1; - setadd32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x08: /*DEC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp - 1); if (cpu_state.abrt) return 1; - setsub32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp + 1); + if (cpu_state.abrt) + return 1; + setadd32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x08: /*DEC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp - 1); + if (cpu_state.abrt) + return 1; + setsub32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 1); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); + if (cpu_state.abrt) + return 1; - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 1); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } + CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 1); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(temp); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(temp); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 1); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } diff --git a/src/cpu/x86_ops_cyrix.h b/src/cpu/x86_ops_cyrix.h index 500b119fb..672ebd08e 100644 --- a/src/cpu/x86_ops_cyrix.h +++ b/src/cpu/x86_ops_cyrix.h @@ -1,272 +1,265 @@ /*Cyrix-only instructions*/ /*System Management Mode*/ -static void opSVDC_common(uint32_t fetchdat) +static void +opSVDC_common(uint32_t fetchdat) { - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es); - writememw(0, easeg+cpu_state.eaaddr+8, ES); - break; - case 0x08: /*CS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_cs); - writememw(0, easeg+cpu_state.eaaddr+8, CS); - break; - case 0x18: /*DS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds); - writememw(0, easeg+cpu_state.eaaddr+8, DS); - break; - case 0x10: /*SS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss); - writememw(0, easeg+cpu_state.eaaddr+8, SS); - break; - case 0x20: /*FS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs); - writememw(0, easeg+cpu_state.eaaddr+8, FS); - break; - case 0x28: /*GS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs); - writememw(0, easeg+cpu_state.eaaddr+8, GS); - break; - default: - x86illegal(); - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); + writememw(0, easeg + cpu_state.eaaddr + 8, ES); + break; + case 0x08: /*CS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_cs); + writememw(0, easeg + cpu_state.eaaddr + 8, CS); + break; + case 0x18: /*DS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); + writememw(0, easeg + cpu_state.eaaddr + 8, DS); + break; + case 0x10: /*SS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); + writememw(0, easeg + cpu_state.eaaddr + 8, SS); + break; + case 0x20: /*FS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); + writememw(0, easeg + cpu_state.eaaddr + 8, FS); + break; + case 0x28: /*GS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); + writememw(0, easeg + cpu_state.eaaddr + 8, GS); + break; + default: + x86illegal(); + } } -static int opSVDC_a16(uint32_t fetchdat) +static int +opSVDC_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - opSVDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVDC_a32(uint32_t fetchdat) +static int +opSVDC_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - opSVDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static void opRSDC_common(uint32_t fetchdat) +static void +opRSDC_common(uint32_t fetchdat) { - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss); - break; - case 0x20: /*FS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs); - break; - default: - x86illegal(); - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); + break; + case 0x20: /*FS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); + break; + default: + x86illegal(); + } } -static int opRSDC_a16(uint32_t fetchdat) +static int +opRSDC_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - opRSDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSDC_a32(uint32_t fetchdat) +static int +opRSDC_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - opRSDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVLDT_a16(uint32_t fetchdat) +static int +opSVLDT_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVLDT_a32(uint32_t fetchdat) +static int +opSVLDT_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSLDT_a16(uint32_t fetchdat) +static int +opRSLDT_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSLDT_a32(uint32_t fetchdat) +static int +opRSLDT_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVTS_a16(uint32_t fetchdat) +static int +opSVTS_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVTS_a32(uint32_t fetchdat) +static int +opSVTS_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSTS_a16(uint32_t fetchdat) +static int +opRSTS_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSTS_a32(uint32_t fetchdat) +static int +opRSTS_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSMINT(uint32_t fetchdat) +static int +opSMINT(uint32_t fetchdat) { - if (in_smm) - fatal("opSMINT\n"); - else - x86illegal(); + if (in_smm) + fatal("opSMINT\n"); + else + x86illegal(); - return 1; + return 1; } -static int opRDSHR_a16(uint32_t fetchdat) +static int +opRDSHR_a16(uint32_t fetchdat) { - if (in_smm) - fatal("opRDSHR_a16\n"); - else - x86illegal(); + if (in_smm) + fatal("opRDSHR_a16\n"); + else + x86illegal(); - return 1; + return 1; } -static int opRDSHR_a32(uint32_t fetchdat) +static int +opRDSHR_a32(uint32_t fetchdat) { - if (in_smm) - fatal("opRDSHR_a32\n"); - else - x86illegal(); + if (in_smm) + fatal("opRDSHR_a32\n"); + else + x86illegal(); - return 1; + return 1; } -static int opWRSHR_a16(uint32_t fetchdat) +static int +opWRSHR_a16(uint32_t fetchdat) { - if (in_smm) - fatal("opWRSHR_a16\n"); - else - x86illegal(); + if (in_smm) + fatal("opWRSHR_a16\n"); + else + x86illegal(); - return 1; + return 1; } -static int opWRSHR_a32(uint32_t fetchdat) +static int +opWRSHR_a32(uint32_t fetchdat) { - if (in_smm) - fatal("opWRSHR_a32\n"); - else - x86illegal(); + if (in_smm) + fatal("opWRSHR_a32\n"); + else + x86illegal(); - return 1; + return 1; } diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index 16215b525..f08b30fce 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -1,313 +1,319 @@ -static int opCMC(uint32_t fetchdat) +static int +opCMC(uint32_t fetchdat) { - flags_rebuild(); - cpu_state.flags ^= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + cpu_state.flags ^= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } - -static int opCLC(uint32_t fetchdat) +static int +opCLC(uint32_t fetchdat) { - flags_rebuild(); - cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCLD(uint32_t fetchdat) +static int +opCLD(uint32_t fetchdat) { - cpu_state.flags &= ~D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + cpu_state.flags &= ~D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCLI(uint32_t fetchdat) +static int +opCLI(uint32_t fetchdat) { - if (!IOPLp) - { - if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) - { - cpu_state.eflags &= ~VIF_FLAG; - } - else - { - x86gpf(NULL,0); - return 1; - } + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + cpu_state.eflags &= ~VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; } + } else + cpu_state.flags &= ~I_FLAG; + + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSTC(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTD(uint32_t fetchdat) +{ + cpu_state.flags |= D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTI(uint32_t fetchdat) +{ + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + if (cpu_state.eflags & VIP_FLAG) { + x86gpf(NULL, 0); + return 1; + } else + cpu_state.eflags |= VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; + } + } else + cpu_state.flags |= I_FLAG; + + /*First instruction after STI will always execute, regardless of whether + there is a pending interrupt*/ + cpu_end_block_after_ins = 2; + + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSAHF(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opLAHF(uint32_t fetchdat) +{ + flags_rebuild(); + AH = cpu_state.flags & 0xff; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opPUSHF(uint32_t fetchdat) +{ + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint16_t temp; + + flags_rebuild(); + temp = (cpu_state.flags & ~I_FLAG) | 0x3000; + if (cpu_state.eflags & VIF_FLAG) + temp |= I_FLAG; + PUSH_W(temp); + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + flags_rebuild(); + PUSH_W(cpu_state.flags); + } + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opPUSHFD(uint32_t fetchdat) +{ + uint16_t tempw; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + if (cpu_CR4_mask & CR4_VME) + tempw = cpu_state.eflags & 0x3c; + else if (CPUID) + tempw = cpu_state.eflags & 0x24; + else + tempw = cpu_state.eflags & 4; + flags_rebuild(); + PUSH_L(cpu_state.flags | (tempw << 16)); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; +} + +static int +opPOPF_186(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF_286(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint32_t old_esp = ESP; + + tempw = POP_W(); + if (cpu_state.abrt) { + + ESP = old_esp; + return 1; + } + + if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + ESP = old_esp; + x86gpf(NULL, 0); + return 1; + } + if (tempw & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; else - cpu_state.flags &= ~I_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } + flags_extract(); - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opSTC(uint32_t fetchdat) -{ - flags_rebuild(); - cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opSTD(uint32_t fetchdat) -{ - cpu_state.flags |= D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opSTI(uint32_t fetchdat) -{ - if (!IOPLp) - { - if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) - { - if (cpu_state.eflags & VIP_FLAG) - { - x86gpf(NULL,0); - return 1; - } - else - cpu_state.eflags |= VIF_FLAG; - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - cpu_state.flags |= I_FLAG; - - /*First instruction after STI will always execute, regardless of whether - there is a pending interrupt*/ - cpu_end_block_after_ins = 2; - - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opSAHF(uint32_t fetchdat) -{ - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); #if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; + codegen_flags_changed = 0; #endif - return 0; + return 0; } -static int opLAHF(uint32_t fetchdat) +static int +opPOPFD(uint32_t fetchdat) { - flags_rebuild(); - AH = cpu_state.flags & 0xff; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} + uint32_t templ; -static int opPUSHF(uint32_t fetchdat) -{ - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - if (cr4 & CR4_VME) - { - uint16_t temp; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } - flags_rebuild(); - temp = (cpu_state.flags & ~I_FLAG) | 0x3000; - if (cpu_state.eflags & VIF_FLAG) - temp |= I_FLAG; - PUSH_W(temp); - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - { - flags_rebuild(); - PUSH_W(cpu_state.flags); - } - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opPUSHFD(uint32_t fetchdat) -{ - uint16_t tempw; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - if (cpu_CR4_mask & CR4_VME) tempw = cpu_state.eflags & 0x3c; - else if (CPUID) tempw = cpu_state.eflags & 0x24; - else tempw = cpu_state.eflags & 4; - flags_rebuild(); - PUSH_L(cpu_state.flags | (tempw << 16)); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} + templ = POP_L(); + if (cpu_state.abrt) + return 1; -static int opPOPF_186(uint32_t fetchdat) -{ - uint16_t tempw; + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (templ & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } + templ &= (is486 || isibm486) ? 0x3c0000 : 0; + templ |= ((cpu_state.eflags & 3) << 16); + if (cpu_CR4_mask & CR4_VME) + cpu_state.eflags = (templ >> 16) & 0x3f; + else if (CPUID) + cpu_state.eflags = (templ >> 16) & 0x27; + else if (is486 || isibm486) + cpu_state.eflags = (templ >> 16) & 7; + else + cpu_state.eflags = (templ >> 16) & 3; - tempw = POP_W(); if (cpu_state.abrt) return 1; + flags_extract(); - if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); #if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; + codegen_flags_changed = 0; #endif - return 0; -} -static int opPOPF_286(uint32_t fetchdat) -{ - uint16_t tempw; - - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - - tempw = POP_W(); if (cpu_state.abrt) return 1; - - if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; -#endif - - return 0; -} -static int opPOPF(uint32_t fetchdat) -{ - uint16_t tempw; - - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - if (cr4 & CR4_VME) - { - uint32_t old_esp = ESP; - - tempw = POP_W(); - if (cpu_state.abrt) - { - - ESP = old_esp; - return 1; - } - - if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) - { - ESP = old_esp; - x86gpf(NULL, 0); - return 1; - } - if (tempw & I_FLAG) - cpu_state.eflags |= VIF_FLAG; - else - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - } - else - { - x86gpf(NULL, 0); - return 1; - } - } - else - { - tempw = POP_W(); - if (cpu_state.abrt) - return 1; - - if (!(CPL) || !(msw & 1)) - cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - } - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; -#endif - - return 0; -} -static int opPOPFD(uint32_t fetchdat) -{ - uint32_t templ; - - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - - templ = POP_L(); if (cpu_state.abrt) return 1; - - if (!(CPL) || !(msw & 1)) cpu_state.flags = (templ & 0x7fd5) | 2; - else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; - else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - - templ &= (is486 || isibm486) ? 0x3c0000 : 0; - templ |= ((cpu_state.eflags&3) << 16); - if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f; - else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27; - else if (is486 || isibm486) cpu_state.eflags = (templ >> 16) & 7; - else cpu_state.eflags = (templ >> 16) & 3; - - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); - -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; -#endif - - return 0; + return 0; } diff --git a/src/cpu/x86_ops_fpu.h b/src/cpu/x86_ops_fpu.h index a1976f268..314ec321b 100644 --- a/src/cpu/x86_ops_fpu.h +++ b/src/cpu/x86_ops_fpu.h @@ -1,85 +1,101 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -static int opESCAPE_d8_a16(uint32_t fetchdat) +static int +opESCAPE_d8_a16(uint32_t fetchdat) { - return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_d8_a32(uint32_t fetchdat) +static int +opESCAPE_d8_a32(uint32_t fetchdat) { - return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_d9_a16(uint32_t fetchdat) +static int +opESCAPE_d9_a16(uint32_t fetchdat) { - return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_d9_a32(uint32_t fetchdat) +static int +opESCAPE_d9_a32(uint32_t fetchdat) { - return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_da_a16(uint32_t fetchdat) +static int +opESCAPE_da_a16(uint32_t fetchdat) { - return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_da_a32(uint32_t fetchdat) +static int +opESCAPE_da_a32(uint32_t fetchdat) { - return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_db_a16(uint32_t fetchdat) +static int +opESCAPE_db_a16(uint32_t fetchdat) { - return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_db_a32(uint32_t fetchdat) +static int +opESCAPE_db_a32(uint32_t fetchdat) { - return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_dc_a16(uint32_t fetchdat) +static int +opESCAPE_dc_a16(uint32_t fetchdat) { - return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_dc_a32(uint32_t fetchdat) +static int +opESCAPE_dc_a32(uint32_t fetchdat) { - return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_dd_a16(uint32_t fetchdat) +static int +opESCAPE_dd_a16(uint32_t fetchdat) { - return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_dd_a32(uint32_t fetchdat) +static int +opESCAPE_dd_a32(uint32_t fetchdat) { - return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_de_a16(uint32_t fetchdat) +static int +opESCAPE_de_a16(uint32_t fetchdat) { - return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_de_a32(uint32_t fetchdat) +static int +opESCAPE_de_a32(uint32_t fetchdat) { - return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_df_a16(uint32_t fetchdat) +static int +opESCAPE_df_a16(uint32_t fetchdat) { - return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_df_a32(uint32_t fetchdat) +static int +opESCAPE_df_a32(uint32_t fetchdat) { - return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); } -static int opWAIT(uint32_t fetchdat) +static int +opWAIT(uint32_t fetchdat) { - if ((cr0 & 0xa) == 0xa) - { - x86_int(7); - return 1; - } - CLOCK_CYCLES(4); - return 0; + if ((cr0 & 0xa) == 0xa) { + x86_int(7); + return 1; + } + CLOCK_CYCLES(4); + return 0; } diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index 3f2d85766..8940a98a0 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -1,17 +1,17 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * x86 i686 (Pentium Pro/Pentium II) CPU Instructions. + * x86 i686 (Pentium Pro/Pentium II) CPU Instructions. * * * - * Author: Miran Grca, - * Copyright 2016-2020 Miran Grca. + * Authors: Miran Grca, + * Copyright 2016-2020 Miran Grca. */ static int opSYSENTER(uint32_t fetchdat) @@ -19,65 +19,63 @@ opSYSENTER(uint32_t fetchdat) int ret = sysenter(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; } - static int opSYSEXIT(uint32_t fetchdat) { int ret = sysexit(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; } - static int fx_save_stor_common(uint32_t fetchdat, int bits) { - uint8_t fxinst = 0; - uint16_t twd = x87_gettag(); - uint32_t old_eaaddr = 0; - uint8_t ftwb = 0; - uint16_t rec_ftw = 0; - uint16_t fpus = 0; + uint8_t fxinst = 0; + uint16_t twd = x87_gettag(); + uint32_t old_eaaddr = 0; + uint8_t ftwb = 0; + uint16_t rec_ftw = 0; + uint16_t fpus = 0; uint64_t *p; if (CPUID < 0x650) - return ILLEGAL(fetchdat); + return ILLEGAL(fetchdat); FP_ENTER(); if (bits == 32) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); } else { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); } if (cpu_state.eaaddr & 0xf) { - x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr); - x86gpf(NULL, 0); - return cpu_state.abrt; + x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr); + x86gpf(NULL, 0); + return cpu_state.abrt; } fxinst = (rmdat >> 3) & 7; if ((fxinst > 1) || (cpu_mod == 3)) { - x86illegal(); - return cpu_state.abrt; + x86illegal(); + return cpu_state.abrt; } FP_ENTER(); @@ -85,170 +83,186 @@ fx_save_stor_common(uint32_t fetchdat, int bits) old_eaaddr = cpu_state.eaaddr; if (fxinst == 1) { - /* FXRSTOR */ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - fpus = readmemw(easeg, cpu_state.eaaddr + 2); - cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.TOP = (fpus >> 11) & 7; - cpu_state.npxs &= fpus & ~0x3800; + /* FXRSTOR */ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + fpus = readmemw(easeg, cpu_state.eaaddr + 2); + cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.TOP = (fpus >> 11) & 7; + cpu_state.npxs &= fpus & ~0x3800; - x87_pc_off = readmeml(easeg, cpu_state.eaaddr+8); - x87_pc_seg = readmemw(easeg, cpu_state.eaaddr+12); + x87_pc_off = readmeml(easeg, cpu_state.eaaddr + 8); + x87_pc_seg = readmemw(easeg, cpu_state.eaaddr + 12); - ftwb = readmemb(easeg, cpu_state.eaaddr + 4); + ftwb = readmemb(easeg, cpu_state.eaaddr + 4); - if (ftwb & 0x01) rec_ftw |= 0x0003; - if (ftwb & 0x02) rec_ftw |= 0x000C; - if (ftwb & 0x04) rec_ftw |= 0x0030; - if (ftwb & 0x08) rec_ftw |= 0x00C0; - if (ftwb & 0x10) rec_ftw |= 0x0300; - if (ftwb & 0x20) rec_ftw |= 0x0C00; - if (ftwb & 0x40) rec_ftw |= 0x3000; - if (ftwb & 0x80) rec_ftw |= 0xC000; + if (ftwb & 0x01) + rec_ftw |= 0x0003; + if (ftwb & 0x02) + rec_ftw |= 0x000C; + if (ftwb & 0x04) + rec_ftw |= 0x0030; + if (ftwb & 0x08) + rec_ftw |= 0x00C0; + if (ftwb & 0x10) + rec_ftw |= 0x0300; + if (ftwb & 0x20) + rec_ftw |= 0x0C00; + if (ftwb & 0x40) + rec_ftw |= 0x3000; + if (ftwb & 0x80) + rec_ftw |= 0xC000; - x87_op_off = readmeml(easeg, cpu_state.eaaddr+16); - x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16; - x87_op_seg = readmemw(easeg, cpu_state.eaaddr+20); + x87_op_off = readmeml(easeg, cpu_state.eaaddr + 16); + x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16; + x87_op_seg = readmemw(easeg, cpu_state.eaaddr + 20); - cpu_state.eaaddr = old_eaaddr + 32; - x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); x87_ld_frstor(0); + cpu_state.eaaddr = old_eaaddr + 32; + x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); + x87_ld_frstor(0); - cpu_state.eaaddr = old_eaaddr + 48; - x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); x87_ld_frstor(1); + cpu_state.eaaddr = old_eaaddr + 48; + x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); + x87_ld_frstor(1); - cpu_state.eaaddr = old_eaaddr + 64; - x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); x87_ld_frstor(2); + cpu_state.eaaddr = old_eaaddr + 64; + x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); + x87_ld_frstor(2); - cpu_state.eaaddr = old_eaaddr + 80; - x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); x87_ld_frstor(3); + cpu_state.eaaddr = old_eaaddr + 80; + x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); + x87_ld_frstor(3); - cpu_state.eaaddr = old_eaaddr + 96; - x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); x87_ld_frstor(4); + cpu_state.eaaddr = old_eaaddr + 96; + x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); + x87_ld_frstor(4); - cpu_state.eaaddr = old_eaaddr + 112; - x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); x87_ld_frstor(5); + cpu_state.eaaddr = old_eaaddr + 112; + x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); + x87_ld_frstor(5); - cpu_state.eaaddr = old_eaaddr + 128; - x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); x87_ld_frstor(6); + cpu_state.eaaddr = old_eaaddr + 128; + x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); + x87_ld_frstor(6); - cpu_state.eaaddr = old_eaaddr + 144; - x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); x87_ld_frstor(7); + cpu_state.eaaddr = old_eaaddr + 144; + x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); + x87_ld_frstor(7); - cpu_state.ismmx = 0; - /*Horrible hack, but as 86Box doesn't keep the FPU stack in 80-bit precision at all times - something like this is needed*/ - p = (uint64_t *) cpu_state.tag; + cpu_state.ismmx = 0; + /*Horrible hack, but as 86Box doesn't keep the FPU stack in 80-bit precision at all times + something like this is needed*/ + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && (*p == 0x0101010101010101ull)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ull)) #else - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && !(*p)) #endif - cpu_state.ismmx = 1; + cpu_state.ismmx = 1; - x87_settag(rec_ftw); + x87_settag(rec_ftw); - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + CLOCK_CYCLES((cr0 & 1) ? 34 : 44); } else { - /* FXSAVE */ - if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; - if ((twd & 0x000C) == 0x000C) ftwb |= 0x02; - if ((twd & 0x0030) == 0x0030) ftwb |= 0x04; - if ((twd & 0x00C0) == 0x00C0) ftwb |= 0x08; - if ((twd & 0x0300) == 0x0300) ftwb |= 0x10; - if ((twd & 0x0C00) == 0x0C00) ftwb |= 0x20; - if ((twd & 0x3000) == 0x3000) ftwb |= 0x40; - if ((twd & 0xC000) == 0xC000) ftwb |= 0x80; + /* FXSAVE */ + if ((twd & 0x0003) == 0x0003) + ftwb |= 0x01; + if ((twd & 0x000C) == 0x000C) + ftwb |= 0x02; + if ((twd & 0x0030) == 0x0030) + ftwb |= 0x04; + if ((twd & 0x00C0) == 0x00C0) + ftwb |= 0x08; + if ((twd & 0x0300) == 0x0300) + ftwb |= 0x10; + if ((twd & 0x0C00) == 0x0C00) + ftwb |= 0x20; + if ((twd & 0x3000) == 0x3000) + ftwb |= 0x40; + if ((twd & 0xC000) == 0xC000) + ftwb |= 0x80; - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememb(easeg,cpu_state.eaaddr+4,ftwb); + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememb(easeg, cpu_state.eaaddr + 4, ftwb); - writememw(easeg,cpu_state.eaaddr+6,(x87_op_off>>16)<<12); - writememl(easeg,cpu_state.eaaddr+8,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_seg); + writememw(easeg, cpu_state.eaaddr + 6, (x87_op_off >> 16) << 12); + writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 12, x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+16,x87_op_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_seg); + writememl(easeg, cpu_state.eaaddr + 16, x87_op_off); + writememw(easeg, cpu_state.eaaddr + 20, x87_op_seg); - cpu_state.eaaddr = old_eaaddr + 32; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0); + cpu_state.eaaddr = old_eaaddr + 32; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0); - cpu_state.eaaddr = old_eaaddr + 48; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1); + cpu_state.eaaddr = old_eaaddr + 48; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1); - cpu_state.eaaddr = old_eaaddr + 64; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2); + cpu_state.eaaddr = old_eaaddr + 64; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2); - cpu_state.eaaddr = old_eaaddr + 80; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3); + cpu_state.eaaddr = old_eaaddr + 80; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3); - cpu_state.eaaddr = old_eaaddr + 96; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4); + cpu_state.eaaddr = old_eaaddr + 96; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4); - cpu_state.eaaddr = old_eaaddr + 112; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5); + cpu_state.eaaddr = old_eaaddr + 112; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5); - cpu_state.eaaddr = old_eaaddr + 128; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6); + cpu_state.eaaddr = old_eaaddr + 128; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6); - cpu_state.eaaddr = old_eaaddr + 144; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7); + cpu_state.eaaddr = old_eaaddr + 144; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7); - cpu_state.eaaddr = old_eaaddr; + cpu_state.eaaddr = old_eaaddr; - cpu_state.npxc = 0x37F; + cpu_state.npxc = 0x37F; codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; + cpu_state.npxs = 0; + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC *p = 0; #else *p = 0x0303030303030303ll; #endif - cpu_state.TOP = 0; - cpu_state.ismmx = 0; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); } return cpu_state.abrt; } - static int opFXSAVESTOR_a16(uint32_t fetchdat) { return fx_save_stor_common(fetchdat, 16); } - static int opFXSAVESTOR_a32(uint32_t fetchdat) { return fx_save_stor_common(fetchdat, 32); } - static int opHINT_NOP_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); return 0; } - static int opHINT_NOP_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); return 0; } diff --git a/src/cpu/x86_ops_inc_dec.h b/src/cpu/x86_ops_inc_dec.h index 682662851..3eb908c57 100644 --- a/src/cpu/x86_ops_inc_dec.h +++ b/src/cpu/x86_ops_inc_dec.h @@ -1,12 +1,12 @@ -#define INC_DEC_OP(name, reg, inc, setflags) \ - static int op ## name (uint32_t fetchdat) \ - { \ - setflags(reg, 1); \ - reg += inc; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); \ - return 0; \ - } +#define INC_DEC_OP(name, reg, inc, setflags) \ + static int op##name(uint32_t fetchdat) \ + { \ + setflags(reg, 1); \ + reg += inc; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 1, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } INC_DEC_OP(INC_AX, AX, 1, setadd16nc) INC_DEC_OP(INC_BX, BX, 1, setadd16nc) @@ -44,50 +44,57 @@ INC_DEC_OP(DEC_EDI, EDI, -1, setsub32nc) INC_DEC_OP(DEC_EBP, EBP, -1, setsub32nc) INC_DEC_OP(DEC_ESP, ESP, -1, setsub32nc) - -static int opINCDEC_b_a16(uint32_t fetchdat) +static int +opINCDEC_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp=geteab(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; - if (rmdat&0x38) - { - seteab(temp - 1); if (cpu_state.abrt) return 1; - setsub8nc(temp, 1); - } - else - { - seteab(temp + 1); if (cpu_state.abrt) return 1; - setadd8nc(temp, 1); - } - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + if (rmdat & 0x38) { + seteab(temp - 1); + if (cpu_state.abrt) + return 1; + setsub8nc(temp, 1); + } else { + seteab(temp + 1); + if (cpu_state.abrt) + return 1; + setadd8nc(temp, 1); + } + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opINCDEC_b_a32(uint32_t fetchdat) +static int +opINCDEC_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp=geteab(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; - if (rmdat&0x38) - { - seteab(temp - 1); if (cpu_state.abrt) return 1; - setsub8nc(temp, 1); - } - else - { - seteab(temp + 1); if (cpu_state.abrt) return 1; - setadd8nc(temp, 1); - } - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; + if (rmdat & 0x38) { + seteab(temp - 1); + if (cpu_state.abrt) + return 1; + setsub8nc(temp, 1); + } else { + seteab(temp + 1); + if (cpu_state.abrt) + return 1; + setadd8nc(temp, 1); + } + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_int.h b/src/cpu/x86_ops_int.h index 0074aec29..a73ed62e0 100644 --- a/src/cpu/x86_ops_int.h +++ b/src/cpu/x86_ops_int.h @@ -1,94 +1,96 @@ -static int opINT3(uint32_t fetchdat) +static int +opINT3(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); #ifdef USE_GDBSTUB - if (gdbstub_int3()) - return 1; + if (gdbstub_int3()) + return 1; #endif - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - x86_int_sw(3); - CLOCK_CYCLES((is486) ? 44 : 59); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); return 1; + } + x86_int_sw(3); + CLOCK_CYCLES((is486) ? 44 : 59); + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0); + return 1; } -static int opINT1(uint32_t fetchdat) +static int +opINT1(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - x86_int_sw(1); - CLOCK_CYCLES((is486) ? 44 : 59); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); + int cycles_old = cycles; + UN_USED(cycles_old); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); return 1; + } + x86_int_sw(1); + CLOCK_CYCLES((is486) ? 44 : 59); + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0); + return 1; } -static int opINT(uint32_t fetchdat) +static int +opINT(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); - uint8_t temp = getbytef(); + int cycles_old = cycles; + UN_USED(cycles_old); + uint8_t temp = getbytef(); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - if (cr4 & CR4_VME) - { - uint16_t t; - uint8_t d; + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + if (cr4 & CR4_VME) { + uint16_t t; + uint8_t d; - cpl_override = 1; - t = readmemw(tr.base, 0x66) - 32; - cpl_override = 0; - if (cpu_state.abrt) return 1; + cpl_override = 1; + t = readmemw(tr.base, 0x66) - 32; + cpl_override = 0; + if (cpu_state.abrt) + return 1; - t += (temp >> 3); - if (t <= tr.limit) - { - cpl_override = 1; - d = readmemb(tr.base, t);// + (temp >> 3)); - cpl_override = 0; - if (cpu_state.abrt) return 1; + t += (temp >> 3); + if (t <= tr.limit) { + cpl_override = 1; + d = readmemb(tr.base, t); // + (temp >> 3)); + cpl_override = 0; + if (cpu_state.abrt) + return 1; - if (!(d & (1 << (temp & 7)))) - { - x86_int_sw_rm(temp); - PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); - return 1; - } - } + if (!(d & (1 << (temp & 7)))) { + x86_int_sw_rm(temp); + PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0); + return 1; } - x86gpf_expected(NULL,0); - return 1; + } } - - x86_int_sw(temp); - PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); + x86gpf_expected(NULL, 0); return 1; + } + + x86_int_sw(temp); + PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0); + return 1; } -static int opINTO(uint32_t fetchdat) +static int +opINTO(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - if (VF_SET()) - { - cpu_state.oldpc = cpu_state.pc; - x86_int_sw(4); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); - return 1; - } - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (VF_SET()) { + cpu_state.oldpc = cpu_state.pc; + x86_int_sw(4); + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0); + return 1; + } + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } diff --git a/src/cpu/x86_ops_io.h b/src/cpu/x86_ops_io.h index 50d7d94d1..c4d46404d 100644 --- a/src/cpu/x86_ops_io.h +++ b/src/cpu/x86_ops_io.h @@ -1,146 +1,158 @@ -static int opIN_AL_imm(uint32_t fetchdat) +static int +opIN_AL_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - AL = inb(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + AL = inb(port); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opIN_AX_imm(uint32_t fetchdat) +static int +opIN_AX_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - AX = inw(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + AX = inw(port); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opIN_EAX_imm(uint32_t fetchdat) +static int +opIN_EAX_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - EAX = inl(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 0,1,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + check_io_perm(port + 2); + check_io_perm(port + 3); + EAX = inl(port); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, -1, 0, 1, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opOUT_AL_imm(uint32_t fetchdat) +static int +opOUT_AL_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - outb(port, AL); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); - if (port == 0x64) - return x86_was_reset; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opOUT_AX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - outw(port, AX); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opOUT_EAX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - outl(port, EAX); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,0,1, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} - -static int opIN_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - AL = inb(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_AX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - AX = inw(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_EAX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - EAX = inl(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 0,1,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} - -static int opOUT_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - outb(DX, AL); - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + outb(port, AL); + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0); + if (port == 0x64) return x86_was_reset; + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opOUT_AX_DX(uint32_t fetchdat) +static int +opOUT_AX_imm(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); - outw(DX, AX); - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + outw(port, AX); + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opOUT_EAX_DX(uint32_t fetchdat) +static int +opOUT_EAX_imm(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - outl(DX, EAX); - PREFETCH_RUN(11, 1, -1, 0,0,0,1, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + check_io_perm(port + 2); + check_io_perm(port + 3); + outl(port, EAX); + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, -1, 0, 0, 0, 1, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} + +static int +opIN_AL_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + AL = inb(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} +static int +opIN_AX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + AX = inw(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} +static int +opIN_EAX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + EAX = inl(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 0, 1, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} + +static int +opOUT_AL_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + outb(DX, AL); + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return x86_was_reset; +} +static int +opOUT_AX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + outw(DX, AX); + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} +static int +opOUT_EAX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + outl(DX, EAX); + PREFETCH_RUN(11, 1, -1, 0, 0, 0, 1, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index 7f9df37d7..a1503a75e 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -1,75 +1,75 @@ -#define cond_O ( VF_SET()) +#define cond_O (VF_SET()) #define cond_NO (!VF_SET()) -#define cond_B ( CF_SET()) +#define cond_B (CF_SET()) #define cond_NB (!CF_SET()) -#define cond_E ( ZF_SET()) +#define cond_E (ZF_SET()) #define cond_NE (!ZF_SET()) -#define cond_BE ( CF_SET() || ZF_SET()) +#define cond_BE (CF_SET() || ZF_SET()) #define cond_NBE (!CF_SET() && !ZF_SET()) -#define cond_S ( NF_SET()) +#define cond_S (NF_SET()) #define cond_NS (!NF_SET()) -#define cond_P ( PF_SET()) +#define cond_P (PF_SET()) #define cond_NP (!PF_SET()) #define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0)) #define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0)) -#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET())) +#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET())) #define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET())) -#define opJ(condition) \ - static int opJ ## condition(uint32_t fetchdat) \ - { \ - int8_t offset = (int8_t)getbytef(); \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - if (!(cpu_state.op32 & 0x100)) \ - cpu_state.pc &= 0xffff; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 2, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opJ ## condition ## _w(uint32_t fetchdat) \ - { \ - int16_t offset = (int16_t)getwordf(); \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - cpu_state.pc &= 0xffff; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 3, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opJ ## condition ## _l(uint32_t fetchdat) \ - { \ - uint32_t offset = getlong(); if (cpu_state.abrt) return 1; \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 5, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 5, -1, 0,0,0,0, 0); \ - return 0; \ - } \ +#define opJ(condition) \ + static int opJ##condition(uint32_t fetchdat) \ + { \ + int8_t offset = (int8_t) getbytef(); \ + CLOCK_CYCLES(timing_bnt); \ + if (cond_##condition) { \ + cpu_state.pc += offset; \ + if (!(cpu_state.op32 & 0x100)) \ + cpu_state.pc &= 0xffff; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 2, -1, 0, 0, 0, 0, 0); \ + PREFETCH_FLUSH(); \ + return 1; \ + } \ + PREFETCH_RUN(timing_bnt, 2, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opJ##condition##_w(uint32_t fetchdat) \ + { \ + int16_t offset = (int16_t) getwordf(); \ + CLOCK_CYCLES(timing_bnt); \ + if (cond_##condition) { \ + cpu_state.pc += offset; \ + cpu_state.pc &= 0xffff; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 3, -1, 0, 0, 0, 0, 0); \ + PREFETCH_FLUSH(); \ + return 1; \ + } \ + PREFETCH_RUN(timing_bnt, 3, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opJ##condition##_l(uint32_t fetchdat) \ + { \ + uint32_t offset = getlong(); \ + if (cpu_state.abrt) \ + return 1; \ + CLOCK_CYCLES(timing_bnt); \ + if (cond_##condition) { \ + cpu_state.pc += offset; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 5, -1, 0, 0, 0, 0, 0); \ + PREFETCH_FLUSH(); \ + return 1; \ + } \ + PREFETCH_RUN(timing_bnt, 5, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } +// clang-format off opJ(O) opJ(NO) opJ(B) @@ -86,295 +86,323 @@ opJ(L) opJ(NL) opJ(LE) opJ(NLE) +// clang-format on - - -static int opLOOPNE_w(uint32_t fetchdat) + static int opLOOPNE_w(uint32_t fetchdat) { - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX && !ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOPNE_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX && !ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opLOOPE_w(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX && ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOPE_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX && ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opLOOP_w(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOP_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opJCXZ(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CLOCK_CYCLES(5); - if (!CX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opJECXZ(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CLOCK_CYCLES(5); - if (!ECX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0); - return 0; -} - - -static int opJMP_r8(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); + int8_t offset = (int8_t) getbytef(); + CX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (CX && !ZF_SET()) { cpu_state.pc += offset; if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 2, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opJMP_r16(uint32_t fetchdat) +static int +opLOOPNE_l(uint32_t fetchdat) { - int16_t offset = (int16_t)getwordf(); + int8_t offset = (int8_t) getbytef(); + ECX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (ECX && !ZF_SET()) { cpu_state.pc += offset; - cpu_state.pc &= 0xffff; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opJMP_r32(uint32_t fetchdat) + +static int +opLOOPE_w(uint32_t fetchdat) { - int32_t offset = (int32_t)getlong(); if (cpu_state.abrt) return 1; + int8_t offset = (int8_t) getbytef(); + CX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (CX && ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 5, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; +} +static int +opLOOPE_l(uint32_t fetchdat) +{ + int8_t offset = (int8_t) getbytef(); + ECX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (ECX && ZF_SET()) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + PREFETCH_FLUSH(); + return 1; + } + return 0; } -static int opJMP_far_a16(uint32_t fetchdat) +static int +opLOOP_w(uint32_t fetchdat) { - uint16_t addr, seg; - uint32_t old_pc; - addr = getwordf(); - seg = getword(); if (cpu_state.abrt) return 1; - old_pc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + int8_t offset = (int8_t) getbytef(); + CX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (CX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - PREFETCH_RUN(11, 5, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opJMP_far_a32(uint32_t fetchdat) +static int +opLOOP_l(uint32_t fetchdat) { - uint16_t seg; - uint32_t addr, old_pc; - addr = getlong(); - seg = getword(); if (cpu_state.abrt) return 1; - old_pc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + int8_t offset = (int8_t) getbytef(); + ECX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (ECX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - PREFETCH_RUN(11, 7, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opCALL_r16(uint32_t fetchdat) +static int +opJCXZ(uint32_t fetchdat) { - int16_t addr = (int16_t)getwordf(); - PUSH_W(cpu_state.pc); - cpu_state.pc += addr; + int8_t offset = (int8_t) getbytef(); + CLOCK_CYCLES(5); + if (!CX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CLOCK_CYCLES(4); + CPU_BLOCK_END(); + PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 1; + } + PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opJECXZ(uint32_t fetchdat) +{ + int8_t offset = (int8_t) getbytef(); + CLOCK_CYCLES(5); + if (!ECX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CLOCK_CYCLES(4); + CPU_BLOCK_END(); + PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 1; + } + PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opJMP_r8(uint32_t fetchdat) +{ + int8_t offset = (int8_t) getbytef(); + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0,0,1,0, 0); - PREFETCH_FLUSH(); - return 0; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opCALL_r32(uint32_t fetchdat) +static int +opJMP_r16(uint32_t fetchdat) { - int32_t addr = getlong(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); - cpu_state.pc += addr; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 5, -1, 0,0,0,1, 0); - PREFETCH_FLUSH(); - return 0; + int16_t offset = (int16_t) getwordf(); + cpu_state.pc += offset; + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 3, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } - -static int opRET_w(uint32_t fetchdat) +static int +opJMP_r32(uint32_t fetchdat) { - uint16_t ret; - - ret = POP_W(); if (cpu_state.abrt) return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 1, -1, 1,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + int32_t offset = (int32_t) getlong(); + if (cpu_state.abrt) + return 1; + cpu_state.pc += offset; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 5, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRET_l(uint32_t fetchdat) + +static int +opJMP_far_a16(uint32_t fetchdat) { - uint32_t ret; - - ret = POP_L(); if (cpu_state.abrt) return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 1, -1, 0,1,0,0, 0); - PREFETCH_FLUSH(); - return 0; + uint16_t addr, seg; + uint32_t old_pc; + addr = getwordf(); + seg = getword(); + if (cpu_state.abrt) + return 1; + old_pc = cpu_state.pc; + cpu_state.pc = addr; + loadcsjmp(seg, old_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } - -static int opRET_w_imm(uint32_t fetchdat) +static int +opJMP_far_a32(uint32_t fetchdat) { - uint16_t ret; - uint16_t offset = getwordf(); - - ret = POP_W(); if (cpu_state.abrt) return 1; - if (stack32) ESP += offset; - else SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 5, -1, 1,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + uint16_t seg; + uint32_t addr, old_pc; + addr = getlong(); + seg = getword(); + if (cpu_state.abrt) + return 1; + old_pc = cpu_state.pc; + cpu_state.pc = addr; + loadcsjmp(seg, old_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRET_l_imm(uint32_t fetchdat) + +static int +opCALL_r16(uint32_t fetchdat) { - uint32_t ret; - uint16_t offset = getwordf(); - - ret = POP_L(); if (cpu_state.abrt) return 1; - if (stack32) ESP += offset; - else SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 5, -1, 0,1,0,0, 0); - PREFETCH_FLUSH(); - return 0; + int16_t addr = (int16_t) getwordf(); + PUSH_W(cpu_state.pc); + cpu_state.pc += addr; + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 3, -1, 0, 0, 1, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opCALL_r32(uint32_t fetchdat) +{ + int32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + PUSH_L(cpu_state.pc); + cpu_state.pc += addr; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 5, -1, 0, 0, 0, 1, 0); + PREFETCH_FLUSH(); + return 0; +} + +static int +opRET_w(uint32_t fetchdat) +{ + uint16_t ret; + + ret = POP_W(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 1, -1, 1, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRET_l(uint32_t fetchdat) +{ + uint32_t ret; + + ret = POP_L(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 1, -1, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} + +static int +opRET_w_imm(uint32_t fetchdat) +{ + uint16_t ret; + uint16_t offset = getwordf(); + + ret = POP_W(); + if (cpu_state.abrt) + return 1; + if (stack32) + ESP += offset; + else + SP += offset; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 5, -1, 1, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRET_l_imm(uint32_t fetchdat) +{ + uint32_t ret; + uint16_t offset = getwordf(); + + ret = POP_L(); + if (cpu_state.abrt) + return 1; + if (stack32) + ESP += offset; + else + SP += offset; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 5, -1, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 7fde5dacc..bd1139ba4 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -1,971 +1,1058 @@ -static int opCBW(uint32_t fetchdat) +static int +opCBW(uint32_t fetchdat) { - AH = (AL & 0x80) ? 0xff : 0; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + AH = (AL & 0x80) ? 0xff : 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCWDE(uint32_t fetchdat) +static int +opCWDE(uint32_t fetchdat) { - EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCWD(uint32_t fetchdat) +static int +opCWD(uint32_t fetchdat) { - DX = (AX & 0x8000) ? 0xFFFF : 0; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + DX = (AX & 0x8000) ? 0xFFFF : 0; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCDQ(uint32_t fetchdat) +static int +opCDQ(uint32_t fetchdat) { - EDX = (EAX & 0x80000000) ? 0xffffffff : 0; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + EDX = (EAX & 0x80000000) ? 0xffffffff : 0; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opNOP(uint32_t fetchdat) +static int +opNOP(uint32_t fetchdat) { - CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + CLOCK_CYCLES((is486) ? 1 : 3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opSETALC(uint32_t fetchdat) +static int +opSETALC(uint32_t fetchdat) { - AL = (CF_SET()) ? 0xff : 0; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); - return 0; + AL = (CF_SET()) ? 0xff : 0; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 1, -1, 0, 0, 0, 0, 0); + return 0; } - - -static int opF6_a16(uint32_t fetchdat) +static int +opF6_a16(uint32_t fetchdat) { - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; - int8_t temps; + int tempws, tempws2 = 0; + uint16_t tempw, src16; + uint8_t src, dst; + int8_t temps; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - } - dst = geteab(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - case 0x08: - src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - setznp8(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x10: /*NOT b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x18: /*NEG b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(0 - dst); if (cpu_state.abrt) return 1; - setsub8(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x20: /*MUL AL,b*/ - AX = AL * dst; - flags_rebuild(); - if (AH) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(13); - PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x28: /*IMUL AL,b*/ - tempws = (int)((int8_t)AL) * (int)((int8_t)dst); - AX = tempws & 0xffff; - flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x30: /*DIV AL,b*/ - src16 = AX; - if (dst) tempw = src16 / dst; - if (dst && !(tempw & 0xff00)) - { - AH = src16 % dst; - AL = (src16 / dst) &0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x38: /*IDIV AL,b*/ - tempws = (int)(int16_t)AX; - if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); - temps = tempws2 & 0xff; - if (dst && ((int)temps == tempws2)) - { - AH = (tempws % (int)((int8_t)dst)) & 0xff; - AL = tempws2 & 0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags|=0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - - default: - x86illegal(); - } - return 0; -} -static int opF6_a32(uint32_t fetchdat) -{ - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; - int8_t temps; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteab(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - case 0x08: - src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - setznp8(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x10: /*NOT b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x18: /*NEG b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(0 - dst); if (cpu_state.abrt) return 1; - setsub8(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x20: /*MUL AL,b*/ - AX = AL * dst; - flags_rebuild(); - if (AH) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(13); - PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x28: /*IMUL AL,b*/ - tempws = (int)((int8_t)AL) * (int)((int8_t)dst); - AX = tempws & 0xffff; - flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x30: /*DIV AL,b*/ - src16 = AX; - if (dst) tempw = src16 / dst; - if (dst && !(tempw & 0xff00)) - { - AH = src16 % dst; - AL = (src16 / dst) &0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x38: /*IDIV AL,b*/ - tempws = (int)(int16_t)AX; - if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); - temps = tempws2 & 0xff; - if (dst && ((int)temps == tempws2)) - { - AH = (tempws % (int)((int8_t)dst)) & 0xff; - AL = tempws2 & 0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - - default: - x86illegal(); - } - return 0; -} - - - -static int opF7_w_a16(uint32_t fetchdat) -{ - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 0; - int16_t temps16; - uint16_t src, dst; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST w*/ - case 0x08: - src = getword(); if (cpu_state.abrt) return 1; - setznp16(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x10: /*NOT w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x18: /*NEG w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(0 - dst); if (cpu_state.abrt) return 1; - setsub16(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x20: /*MUL AX,w*/ - templ = AX * dst; - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (DX) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x28: /*IMUL AX,w*/ - templ = (int)((int16_t)AX) * (int)((int16_t)dst); - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(22); - PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x30: /*DIV AX,w*/ - templ = (DX << 16) | AX; - if (dst) templ2 = templ / dst; - if (dst && !(templ2 & 0xffff0000)) - { - DX = templ % dst; - AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x38: /*IDIV AX,w*/ - tempws = (int)((DX << 16)|AX); - if (dst) tempws2 = tempws / (int)((int16_t)dst); - temps16 = tempws2 & 0xffff; - if ((dst != 0) && ((int)temps16 == tempws2)) - { - DX = tempws % (int)((int16_t)dst); - AX = tempws2 & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - - default: - x86illegal(); - } - return 0; -} -static int opF7_w_a32(uint32_t fetchdat) -{ - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 1; - int16_t temps16; - uint16_t src, dst; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST w*/ - case 0x08: - src = getword(); if (cpu_state.abrt) return 1; - setznp16(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x10: /*NOT w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x18: /*NEG w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(0 - dst); if (cpu_state.abrt) return 1; - setsub16(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x20: /*MUL AX,w*/ - templ = AX * dst; - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (DX) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x28: /*IMUL AX,w*/ - templ = (int)((int16_t)AX) * (int)((int16_t)dst); - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(22); - PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x30: /*DIV AX,w*/ - templ = (DX << 16) | AX; - if (dst) templ2 = templ / dst; - if (dst && !(templ2 & 0xffff0000)) - { - DX = templ % dst; - AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { -// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x38: /*IDIV AX,w*/ - tempws = (int)((DX << 16)|AX); - if (dst) tempws2 = tempws / (int)((int16_t)dst); - temps16 = tempws2 & 0xffff; - if ((dst != 0) && ((int)temps16 == tempws2)) - { - DX = tempws % (int)((int16_t)dst); - AX = tempws2 & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - - default: - x86illegal(); - } - return 0; -} - -static int opF7_l_a16(uint32_t fetchdat) -{ - uint64_t temp64; - uint32_t src, dst; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*TEST l*/ - case 0x08: - src = getlong(); if (cpu_state.abrt) return 1; - setznp32(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x10: /*NOT l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x18: /*NEG l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(0 - dst); if (cpu_state.abrt) return 1; - setsub32(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x20: /*MUL EAX,l*/ - temp64 = (uint64_t)EAX * (uint64_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG); - else cpu_state.flags &= ~(C_FLAG|V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x28: /*IMUL EAX,l*/ - temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(38); - PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x30: /*DIV EAX,l*/ - if (divl(dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES((is486) ? 40 : 38); - PREFETCH_RUN(is486 ? 40:38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x38: /*IDIV EAX,l*/ - if (idivl((int32_t)dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES(43); - PREFETCH_RUN(43, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - - default: - x86illegal(); - } - return 0; -} -static int opF7_l_a32(uint32_t fetchdat) -{ - uint64_t temp64; - uint32_t src, dst; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*TEST l*/ - case 0x08: - src = getlong(); if (cpu_state.abrt) return 1; - setznp32(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x10: /*NOT l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x18: /*NEG l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(0 - dst); if (cpu_state.abrt) return 1; - setsub32(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x20: /*MUL EAX,l*/ - temp64 = (uint64_t)EAX * (uint64_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG); - else cpu_state.flags &= ~(C_FLAG|V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x28: /*IMUL EAX,l*/ - temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(38); - PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x30: /*DIV EAX,l*/ - if (divl(dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES((is486) ? 40 : 38); - PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x38: /*IDIV EAX,l*/ - if (idivl((int32_t)dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES(43); - PREFETCH_RUN(43, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - - default: - x86illegal(); - } - return 0; -} - - -static int opHLT(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - if (smi_line) - enter_smm_check(1); - else if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) - { - CLOCK_CYCLES_ALWAYS(100); - if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) - cpu_state.pc--; - } - else { - CLOCK_CYCLES(5); - } - - CPU_BLOCK_END(); - PREFETCH_RUN(100, 1, -1, 0,0,0,0, 0); - - if (hlt_reset_pending) - softresetx86(); - - return 0; -} - - -static int opLOCK(uint32_t fetchdat) -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 0; - cpu_state.pc++; - - ILLEGAL_ON((fetchdat & 0xff) == 0x90); - - CLOCK_CYCLES(4); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} - - - -static int opBOUND_w_a16(uint32_t fetchdat) -{ - int16_t low, high; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) { SEG_CHECK_READ(cpu_state.ea_seg); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - - if (((int16_t)cpu_state.regs[cpu_reg].w < low) || ((int16_t)cpu_state.regs[cpu_reg].w > high)) - { - x86_int(5); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + } + dst = geteab(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST b,#8*/ + case 0x08: + src = readmemb(cs, cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) return 1; - } + setznp8(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x10: /*NOT b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x18: /*NEG b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(0 - dst); + if (cpu_state.abrt) + return 1; + setsub8(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x20: /*MUL AL,b*/ + AX = AL * dst; + flags_rebuild(); + if (AH) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(13); + PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x28: /*IMUL AL,b*/ + tempws = (int) ((int8_t) AL) * (int) ((int8_t) dst); + AX = tempws & 0xffff; + flags_rebuild(); + if (((int16_t) AX >> 7) != 0 && ((int16_t) AX >> 7) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x30: /*DIV AL,b*/ + src16 = AX; + if (dst) + tempw = src16 / dst; + if (dst && !(tempw & 0xff00)) { + AH = src16 % dst; + AL = (src16 / dst) & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x38: /*IDIV AL,b*/ + tempws = (int) (int16_t) AX; + if (dst != 0) + tempws2 = tempws / (int) ((int8_t) dst); + temps = tempws2 & 0xff; + if (dst && ((int) temps == tempws2)) { + AH = (tempws % (int) ((int8_t) dst)) & 0xff; + AL = tempws2 & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(19); + PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2,0,0,0, 0); - return 0; + default: + x86illegal(); + } + return 0; } -static int opBOUND_w_a32(uint32_t fetchdat) +static int +opF6_a32(uint32_t fetchdat) { - int16_t low, high; + int tempws, tempws2 = 0; + uint16_t tempw, src16; + uint8_t src, dst; + int8_t temps; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - - if (((int16_t)cpu_state.regs[cpu_reg].w < low) || ((int16_t)cpu_state.regs[cpu_reg].w > high)) - { - x86_int(5); + dst = geteab(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST b,#8*/ + case 0x08: + src = readmemb(cs, cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) return 1; - } + setznp8(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x10: /*NOT b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x18: /*NEG b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(0 - dst); + if (cpu_state.abrt) + return 1; + setsub8(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x20: /*MUL AL,b*/ + AX = AL * dst; + flags_rebuild(); + if (AH) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(13); + PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x28: /*IMUL AL,b*/ + tempws = (int) ((int8_t) AL) * (int) ((int8_t) dst); + AX = tempws & 0xffff; + flags_rebuild(); + if (((int16_t) AX >> 7) != 0 && ((int16_t) AX >> 7) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x30: /*DIV AL,b*/ + src16 = AX; + if (dst) + tempw = src16 / dst; + if (dst && !(tempw & 0xff00)) { + AH = src16 % dst; + AL = (src16 / dst) & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x38: /*IDIV AL,b*/ + tempws = (int) (int16_t) AX; + if (dst != 0) + tempws2 = tempws / (int) ((int8_t) dst); + temps = tempws2 & 0xff; + if (dst && ((int) temps == tempws2)) { + AH = (tempws % (int) ((int8_t) dst)) & 0xff; + AL = tempws2 & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(19); + PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2,0,0,0, 1); - return 0; + default: + x86illegal(); + } + return 0; } -static int opBOUND_l_a16(uint32_t fetchdat) +static int +opF7_w_a16(uint32_t fetchdat) { - int32_t low, high; + uint32_t templ, templ2 = 0; + int tempws, tempws2 = 0; + int16_t temps16; + uint16_t src, dst; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - - if (((int32_t)cpu_state.regs[cpu_reg].l < low) || ((int32_t)cpu_state.regs[cpu_reg].l > high)) - { - x86_int(5); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST w*/ + case 0x08: + src = getword(); + if (cpu_state.abrt) return 1; - } + setznp16(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x10: /*NOT w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x18: /*NEG w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(0 - dst); + if (cpu_state.abrt) + return 1; + setsub16(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x20: /*MUL AX,w*/ + templ = AX * dst; + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (DX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x28: /*IMUL AX,w*/ + templ = (int) ((int16_t) AX) * (int) ((int16_t) dst); + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (((int32_t) templ >> 15) != 0 && ((int32_t) templ >> 15) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(22); + PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x30: /*DIV AX,w*/ + templ = (DX << 16) | AX; + if (dst) + templ2 = templ / dst; + if (dst && !(templ2 & 0xffff0000)) { + DX = templ % dst; + AX = (templ / dst) & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x38: /*IDIV AX,w*/ + tempws = (int) ((DX << 16) | AX); + if (dst) + tempws2 = tempws / (int) ((int16_t) dst); + temps16 = tempws2 & 0xffff; + if ((dst != 0) && ((int) temps16 == tempws2)) { + DX = tempws % (int) ((int16_t) dst); + AX = tempws2 & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(27); + PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1,1,0,0, 0); - return 0; + default: + x86illegal(); + } + return 0; } -static int opBOUND_l_a32(uint32_t fetchdat) +static int +opF7_w_a32(uint32_t fetchdat) { - int32_t low, high; + uint32_t templ, templ2 = 0; + int tempws, tempws2 = 1; + int16_t temps16; + uint16_t src, dst; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - - if (((int32_t)cpu_state.regs[cpu_reg].l < low) || ((int32_t)cpu_state.regs[cpu_reg].l > high)) - { - x86_int(5); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST w*/ + case 0x08: + src = getword(); + if (cpu_state.abrt) return 1; - } + setznp16(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x10: /*NOT w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x18: /*NEG w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(0 - dst); + if (cpu_state.abrt) + return 1; + setsub16(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x20: /*MUL AX,w*/ + templ = AX * dst; + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (DX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x28: /*IMUL AX,w*/ + templ = (int) ((int16_t) AX) * (int) ((int16_t) dst); + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (((int32_t) templ >> 15) != 0 && ((int32_t) templ >> 15) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(22); + PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x30: /*DIV AX,w*/ + templ = (DX << 16) | AX; + if (dst) + templ2 = templ / dst; + if (dst && !(templ2 & 0xffff0000)) { + DX = templ % dst; + AX = (templ / dst) & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + // fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x38: /*IDIV AX,w*/ + tempws = (int) ((DX << 16) | AX); + if (dst) + tempws2 = tempws / (int) ((int16_t) dst); + temps16 = tempws2 & 0xffff; + if ((dst != 0) && ((int) temps16 == tempws2)) { + DX = tempws % (int) ((int16_t) dst); + AX = tempws2 & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(27); + PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1,1,0,0, 1); - return 0; + default: + x86illegal(); + } + return 0; } - -static int opCLTS(uint32_t fetchdat) +static int +opF7_l_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); + uint64_t temp64; + uint32_t src, dst; + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + + switch (rmdat & 0x38) { + case 0x00: /*TEST l*/ + case 0x08: + src = getlong(); + if (cpu_state.abrt) return 1; - } - cr0 &= ~8; + setznp32(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x10: /*NOT l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x18: /*NEG l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(0 - dst); + if (cpu_state.abrt) + return 1; + setsub32(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x20: /*MUL EAX,l*/ + temp64 = (uint64_t) EAX * (uint64_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (EDX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x28: /*IMUL EAX,l*/ + temp64 = (int64_t) (int32_t) EAX * (int64_t) (int32_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (((int64_t) temp64 >> 31) != 0 && ((int64_t) temp64 >> 31) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(38); + PREFETCH_RUN(38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x30: /*DIV EAX,l*/ + if (divl(dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES((is486) ? 40 : 38); + PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x38: /*IDIV EAX,l*/ + if (idivl((int32_t) dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES(43); + PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + + default: + x86illegal(); + } + return 0; +} +static int +opF7_l_a32(uint32_t fetchdat) +{ + uint64_t temp64; + uint32_t src, dst; + + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + + switch (rmdat & 0x38) { + case 0x00: /*TEST l*/ + case 0x08: + src = getlong(); + if (cpu_state.abrt) + return 1; + setznp32(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x10: /*NOT l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x18: /*NEG l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(0 - dst); + if (cpu_state.abrt) + return 1; + setsub32(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x20: /*MUL EAX,l*/ + temp64 = (uint64_t) EAX * (uint64_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (EDX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x28: /*IMUL EAX,l*/ + temp64 = (int64_t) (int32_t) EAX * (int64_t) (int32_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (((int64_t) temp64 >> 31) != 0 && ((int64_t) temp64 >> 31) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(38); + PREFETCH_RUN(38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x30: /*DIV EAX,l*/ + if (divl(dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES((is486) ? 40 : 38); + PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x38: /*IDIV EAX,l*/ + if (idivl((int32_t) dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES(43); + PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + + default: + x86illegal(); + } + return 0; +} + +static int +opHLT(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if (smi_line) + enter_smm_check(1); + else if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) { + CLOCK_CYCLES_ALWAYS(100); + if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) + cpu_state.pc--; + } else { CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,0,0,0, 0); - return 0; + } + + CPU_BLOCK_END(); + PREFETCH_RUN(100, 1, -1, 0, 0, 0, 0, 0); + + if (hlt_reset_pending) + softresetx86(); + + return 0; } -static int opINVD(uint32_t fetchdat) +static int +opLOCK(uint32_t fetchdat) { - CLOCK_CYCLES(1000); + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 0; + cpu_state.pc++; + + ILLEGAL_ON((fetchdat & 0xff) == 0x90); + + CLOCK_CYCLES(4); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} + +static int +opBOUND_w_a16(uint32_t fetchdat) +{ + int16_t low, high; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteaw(); + high = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + + if (((int16_t) cpu_state.regs[cpu_reg].w < low) || ((int16_t) cpu_state.regs[cpu_reg].w > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2, 0, 0, 0, 0); + return 0; +} +static int +opBOUND_w_a32(uint32_t fetchdat) +{ + int16_t low, high; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteaw(); + high = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + + if (((int16_t) cpu_state.regs[cpu_reg].w < low) || ((int16_t) cpu_state.regs[cpu_reg].w > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2, 0, 0, 0, 1); + return 0; +} + +static int +opBOUND_l_a16(uint32_t fetchdat) +{ + int32_t low, high; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteal(); + high = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + + if (((int32_t) cpu_state.regs[cpu_reg].l < low) || ((int32_t) cpu_state.regs[cpu_reg].l > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1, 1, 0, 0, 0); + return 0; +} +static int +opBOUND_l_a32(uint32_t fetchdat) +{ + int32_t low, high; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteal(); + high = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + + if (((int32_t) cpu_state.regs[cpu_reg].l < low) || ((int32_t) cpu_state.regs[cpu_reg].l > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1, 1, 0, 0, 1); + return 0; +} + +static int +opCLTS(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + cr0 &= ~8; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opINVD(uint32_t fetchdat) +{ + CLOCK_CYCLES(1000); + CPU_BLOCK_END(); + return 0; +} +static int +opWBINVD(uint32_t fetchdat) +{ + CLOCK_CYCLES(10000); + CPU_BLOCK_END(); + return 0; +} + +static int +opLOADALL(uint32_t fetchdat) +{ + if (CPL && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + msw = (msw & 1) | readmemw(0, 0x806); + cpu_state.flags = (readmemw(0, 0x818) & 0xffd5) | 2; + flags_extract(); + tr.seg = readmemw(0, 0x816); + cpu_state.pc = readmemw(0, 0x81A); + ldt.seg = readmemw(0, 0x81C); + DS = readmemw(0, 0x81E); + SS = readmemw(0, 0x820); + CS = readmemw(0, 0x822); + ES = readmemw(0, 0x824); + DI = readmemw(0, 0x826); + SI = readmemw(0, 0x828); + BP = readmemw(0, 0x82A); + SP = readmemw(0, 0x82C); + BX = readmemw(0, 0x82E); + DX = readmemw(0, 0x830); + CX = readmemw(0, 0x832); + AX = readmemw(0, 0x834); + es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16); + cpu_state.seg_es.access = readmemb(0, 0x839); + cpu_state.seg_es.limit = readmemw(0, 0x83A); + cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); + cpu_state.seg_cs.access = readmemb(0, 0x83F); + cpu_state.seg_cs.limit = readmemw(0, 0x840); + ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); + cpu_state.seg_ss.access = readmemb(0, 0x845); + cpu_state.seg_ss.limit = readmemw(0, 0x846); + if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); + cpu_state.seg_ds.access = readmemb(0, 0x84B); + cpu_state.seg_ds.limit = readmemw(0, 0x84C); + if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); + gdt.limit = readmemw(0, 0x852); + ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); + ldt.access = readmemb(0, 0x857); + ldt.limit = readmemw(0, 0x858); + idt.base = readmemw(0, 0x85A) | (readmemb(0, 0x85C) << 16); + idt.limit = readmemw(0, 0x85E); + tr.base = readmemw(0, 0x860) | (readmemb(0, 0x862) << 16); + tr.access = readmemb(0, 0x863); + tr.limit = readmemw(0, 0x864); + CLOCK_CYCLES(195); + PREFETCH_RUN(195, 1, -1, 51, 0, 0, 0, 0); + return 0; +} + +static void +set_segment_limit(x86seg *s, uint8_t segdat3) +{ + if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/ + { + s->limit_high = s->limit; + s->limit_low = 0; + } else { + s->limit_high = (segdat3 & 0x40) ? 0xffffffff : 0xffff; + s->limit_low = s->limit + 1; + } +} + +static void +loadall_load_segment(uint32_t addr, x86seg *s) +{ + uint32_t attrib = readmeml(0, addr); + uint32_t segdat3 = (attrib >> 16) & 0xff; + s->access = (attrib >> 8) & 0xff; + s->ar_high = segdat3; + s->base = readmeml(0, addr + 4); + s->limit = readmeml(0, addr + 8); + + if (s == &cpu_state.seg_cs) + use32 = (segdat3 & 0x40) ? 0x300 : 0; + if (s == &cpu_state.seg_ss) + stack32 = (segdat3 & 0x40) ? 1 : 0; + + cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); + if (use32) + cpu_cur_status |= CPU_STATUS_USE32; + if (stack32) + cpu_cur_status |= CPU_STATUS_STACK32; + + set_segment_limit(s, segdat3); + + if (s == &cpu_state.seg_ds) { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + } + if (s == &cpu_state.seg_ss) { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + } +} + +static int +opLOADALL386(uint32_t fetchdat) +{ + uint32_t la_addr = es + EDI; + + cr0 = readmeml(0, la_addr); + cpu_state.flags = readmemw(0, la_addr + 4); + cpu_state.eflags = readmemw(0, la_addr + 6); + flags_extract(); + cpu_state.pc = readmeml(0, la_addr + 8); + EDI = readmeml(0, la_addr + 0xC); + ESI = readmeml(0, la_addr + 0x10); + EBP = readmeml(0, la_addr + 0x14); + ESP = readmeml(0, la_addr + 0x18); + EBX = readmeml(0, la_addr + 0x1C); + EDX = readmeml(0, la_addr + 0x20); + ECX = readmeml(0, la_addr + 0x24); + EAX = readmeml(0, la_addr + 0x28); + dr[6] = readmeml(0, la_addr + 0x2C); + dr[7] = readmeml(0, la_addr + 0x30); + tr.seg = readmemw(0, la_addr + 0x34); + ldt.seg = readmemw(0, la_addr + 0x38); + GS = readmemw(0, la_addr + 0x3C); + FS = readmemw(0, la_addr + 0x40); + DS = readmemw(0, la_addr + 0x44); + SS = readmemw(0, la_addr + 0x48); + CS = readmemw(0, la_addr + 0x4C); + ES = readmemw(0, la_addr + 0x50); + + loadall_load_segment(la_addr + 0x54, &tr); + loadall_load_segment(la_addr + 0x60, &idt); + loadall_load_segment(la_addr + 0x6c, &gdt); + loadall_load_segment(la_addr + 0x78, &ldt); + loadall_load_segment(la_addr + 0x84, &cpu_state.seg_gs); + loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs); + loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds); + loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss); + loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs); + loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); + + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + + CLOCK_CYCLES(350); + return 0; +} + +static int +opCPUID(uint32_t fetchdat) +{ + if (CPUID) { + cpu_CPUID(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; +} + +static int +opRDMSR(uint32_t fetchdat) +{ + if (cpu_has_feature(CPU_FEATURE_MSR)) { + cpu_RDMSR(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; +} + +static int +opWRMSR(uint32_t fetchdat) +{ + if (cpu_has_feature(CPU_FEATURE_MSR)) { + cpu_WRMSR(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; +} + +static int +opRSM(uint32_t fetchdat) +{ + if (in_smm) { + leave_smm(); + if (smi_latched) + enter_smm(smm_in_hlt); CPU_BLOCK_END(); return 0; -} -static int opWBINVD(uint32_t fetchdat) -{ - CLOCK_CYCLES(10000); - CPU_BLOCK_END(); - return 0; -} - -static int opLOADALL(uint32_t fetchdat) -{ - if (CPL && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - msw = (msw & 1) | readmemw(0, 0x806); - cpu_state.flags = (readmemw(0, 0x818) & 0xffd5) | 2; - flags_extract(); - tr.seg = readmemw(0, 0x816); - cpu_state.pc = readmemw(0, 0x81A); - ldt.seg = readmemw(0, 0x81C); - DS = readmemw(0, 0x81E); - SS = readmemw(0, 0x820); - CS = readmemw(0, 0x822); - ES = readmemw(0, 0x824); - DI = readmemw(0, 0x826); - SI = readmemw(0, 0x828); - BP = readmemw(0, 0x82A); - SP = readmemw(0, 0x82C); - BX = readmemw(0, 0x82E); - DX = readmemw(0, 0x830); - CX = readmemw(0, 0x832); - AX = readmemw(0, 0x834); - es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16); - cpu_state.seg_es.access = readmemb(0, 0x839); - cpu_state.seg_es.limit = readmemw(0, 0x83A); - cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); - cpu_state.seg_cs.access = readmemb(0, 0x83F); - cpu_state.seg_cs.limit = readmemw(0, 0x840); - ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); - cpu_state.seg_ss.access = readmemb(0, 0x845); - cpu_state.seg_ss.limit = readmemw(0, 0x846); - if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); - cpu_state.seg_ds.access = readmemb(0, 0x84B); - cpu_state.seg_ds.limit = readmemw(0, 0x84C); - if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); - gdt.limit = readmemw(0, 0x852); - ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); - ldt.access = readmemb(0, 0x857); - ldt.limit = readmemw(0, 0x858); - idt.base = readmemw(0, 0x85A) | (readmemb(0, 0x85C) << 16); - idt.limit = readmemw(0, 0x85E); - tr.base = readmemw(0, 0x860) | (readmemb(0, 0x862) << 16); - tr.access = readmemb(0, 0x863); - tr.limit = readmemw(0, 0x864); - CLOCK_CYCLES(195); - PREFETCH_RUN(195, 1, -1, 51,0,0,0, 0); - return 0; -} - -static void set_segment_limit(x86seg *s, uint8_t segdat3) -{ - if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/ - { - s->limit_high = s->limit; - s->limit_low = 0; - } - else - { - s->limit_high = (segdat3 & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; - } -} - -static void loadall_load_segment(uint32_t addr, x86seg *s) -{ - uint32_t attrib = readmeml(0, addr); - uint32_t segdat3 = (attrib >> 16) & 0xff; - s->access = (attrib >> 8) & 0xff; - s->ar_high = segdat3; - s->base = readmeml(0, addr + 4); - s->limit = readmeml(0, addr + 8); - - if (s == &cpu_state.seg_cs) - use32 = (segdat3 & 0x40) ? 0x300 : 0; - if (s == &cpu_state.seg_ss) - stack32 = (segdat3 & 0x40) ? 1 : 0; - - cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); - if (use32) - cpu_cur_status |= CPU_STATUS_USE32; - if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; - - set_segment_limit(s, segdat3); - - if (s == &cpu_state.seg_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - } - if (s == &cpu_state.seg_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - } -} - -static int opLOADALL386(uint32_t fetchdat) -{ - uint32_t la_addr = es + EDI; - - cr0 = readmeml(0, la_addr); - cpu_state.flags = readmemw(0, la_addr + 4); - cpu_state.eflags = readmemw(0, la_addr + 6); - flags_extract(); - cpu_state.pc = readmeml(0, la_addr + 8); - EDI = readmeml(0, la_addr + 0xC); - ESI = readmeml(0, la_addr + 0x10); - EBP = readmeml(0, la_addr + 0x14); - ESP = readmeml(0, la_addr + 0x18); - EBX = readmeml(0, la_addr + 0x1C); - EDX = readmeml(0, la_addr + 0x20); - ECX = readmeml(0, la_addr + 0x24); - EAX = readmeml(0, la_addr + 0x28); - dr[6] = readmeml(0, la_addr + 0x2C); - dr[7] = readmeml(0, la_addr + 0x30); - tr.seg = readmemw(0, la_addr + 0x34); - ldt.seg = readmemw(0, la_addr + 0x38); - GS = readmemw(0, la_addr + 0x3C); - FS = readmemw(0, la_addr + 0x40); - DS = readmemw(0, la_addr + 0x44); - SS = readmemw(0, la_addr + 0x48); - CS = readmemw(0, la_addr + 0x4C); - ES = readmemw(0, la_addr + 0x50); - - loadall_load_segment(la_addr + 0x54, &tr); - loadall_load_segment(la_addr + 0x60, &idt); - loadall_load_segment(la_addr + 0x6c, &gdt); - loadall_load_segment(la_addr + 0x78, &ldt); - loadall_load_segment(la_addr + 0x84, &cpu_state.seg_gs); - loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs); - loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds); - loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss); - loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs); - loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); - - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - - CLOCK_CYCLES(350); - return 0; -} - -static int opCPUID(uint32_t fetchdat) -{ - if (CPUID) - { - cpu_CPUID(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opRDMSR(uint32_t fetchdat) -{ - if (cpu_has_feature(CPU_FEATURE_MSR)) - { - cpu_RDMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opWRMSR(uint32_t fetchdat) -{ - if (cpu_has_feature(CPU_FEATURE_MSR)) - { - cpu_WRMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opRSM(uint32_t fetchdat) -{ - if (in_smm) - { - leave_smm(); - if (smi_latched) - enter_smm(smm_in_hlt); - CPU_BLOCK_END(); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; } diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index f9a7f9357..d270b728f 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -3,47 +3,43 @@ #define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) #define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) -#define MMX_GETSRC() \ - if (cpu_mod == 3) \ - { \ - src = cpu_state.MM[cpu_rm]; \ - CLOCK_CYCLES(1); \ - } \ - else \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ - CLOCK_CYCLES(2); \ - } +#define MMX_GETSRC() \ + if (cpu_mod == 3) { \ + src = cpu_state.MM[cpu_rm]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + src.q = readmemq(easeg, cpu_state.eaaddr); \ + if (cpu_state.abrt) \ + return 1; \ + CLOCK_CYCLES(2); \ + } -#define MMX_ENTER() \ - if (!cpu_has_feature(CPU_FEATURE_MMX)) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 1; \ - } \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ - x87_set_mmx() +#define MMX_ENTER() \ + if (!cpu_has_feature(CPU_FEATURE_MMX)) { \ + cpu_state.pc = cpu_state.oldpc; \ + x86illegal(); \ + return 1; \ + } \ + if (cr0 & 0xc) { \ + x86_int(7); \ + return 1; \ + } \ + x87_set_mmx() -static int opEMMS(uint32_t fetchdat) +static int +opEMMS(uint32_t fetchdat) { - if (!cpu_has_feature(CPU_FEATURE_MMX)) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - x87_emms(); - CLOCK_CYCLES(100); /*Guess*/ - return 0; + if (!cpu_has_feature(CPU_FEATURE_MMX)) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(100); /*Guess*/ + return 0; } diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index afa8aa383..e473f8ec5 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -1,631 +1,660 @@ -static int opPADDB_a16(uint32_t fetchdat) +static int +opPADDB_a16(uint32_t fetchdat) { + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] += src.b[0]; + cpu_state.MM[cpu_reg].b[1] += src.b[1]; + cpu_state.MM[cpu_reg].b[2] += src.b[2]; + cpu_state.MM[cpu_reg].b[3] += src.b[3]; + cpu_state.MM[cpu_reg].b[4] += src.b[4]; + cpu_state.MM[cpu_reg].b[5] += src.b[5]; + cpu_state.MM[cpu_reg].b[6] += src.b[6]; + cpu_state.MM[cpu_reg].b[7] += src.b[7]; + + return 0; +} +static int +opPADDB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] += src.b[0]; + cpu_state.MM[cpu_reg].b[1] += src.b[1]; + cpu_state.MM[cpu_reg].b[2] += src.b[2]; + cpu_state.MM[cpu_reg].b[3] += src.b[3]; + cpu_state.MM[cpu_reg].b[4] += src.b[4]; + cpu_state.MM[cpu_reg].b[5] += src.b[5]; + cpu_state.MM[cpu_reg].b[6] += src.b[6]; + cpu_state.MM[cpu_reg].b[7] += src.b[7]; + + return 0; +} + +static int +opPADDW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] += src.w[0]; + cpu_state.MM[cpu_reg].w[1] += src.w[1]; + cpu_state.MM[cpu_reg].w[2] += src.w[2]; + cpu_state.MM[cpu_reg].w[3] += src.w[3]; + + return 0; +} +static int +opPADDW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] += src.w[0]; + cpu_state.MM[cpu_reg].w[1] += src.w[1]; + cpu_state.MM[cpu_reg].w[2] += src.w[2]; + cpu_state.MM[cpu_reg].w[3] += src.w[3]; + + return 0; +} + +static int +opPADDD_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; + + return 0; +} +static int +opPADDD_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; + + return 0; +} + +static int +opPADDSB_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + + return 0; +} +static int +opPADDSB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + + return 0; +} + +static int +opPADDUSB_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + + return 0; +} +static int +opPADDUSB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + + return 0; +} + +static int +opPADDSW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + + return 0; +} +static int +opPADDSW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + + return 0; +} + +static int +opPADDUSW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + + return 0; +} +static int +opPADDUSW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + + return 0; +} + +static int +opPMADDWD_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) + cpu_state.MM[cpu_reg].l[0] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + + if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) + cpu_state.MM[cpu_reg].l[1] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + + return 0; +} +static int +opPMADDWD_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) + cpu_state.MM[cpu_reg].l[0] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + + if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) + cpu_state.MM[cpu_reg].l[1] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + + return 0; +} + +static int +opPMULLW_a16(uint32_t fetchdat) +{ + MMX_ENTER(); + + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; + cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; + cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; + cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= src.w[0]; + cpu_state.MM[cpu_reg].w[1] *= src.w[1]; + cpu_state.MM[cpu_reg].w[2] *= src.w[2]; + cpu_state.MM[cpu_reg].w[3] *= src.w[3]; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDB_a32(uint32_t fetchdat) +static int +opPMULLW_a32(uint32_t fetchdat) { + MMX_ENTER(); + + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; + cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; + cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; + cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= src.w[0]; + cpu_state.MM[cpu_reg].w[1] *= src.w[1]; + cpu_state.MM[cpu_reg].w[2] *= src.w[2]; + cpu_state.MM[cpu_reg].w[3] *= src.w[3]; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDW_a16(uint32_t fetchdat) +static int +opPMULHW_a16(uint32_t fetchdat) { + MMX_ENTER(); + + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDW_a32(uint32_t fetchdat) +static int +opPMULHW_a32(uint32_t fetchdat) { + MMX_ENTER(); + + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDD_a16(uint32_t fetchdat) +static int +opPSUBB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + cpu_state.MM[cpu_reg].b[0] -= src.b[0]; + cpu_state.MM[cpu_reg].b[1] -= src.b[1]; + cpu_state.MM[cpu_reg].b[2] -= src.b[2]; + cpu_state.MM[cpu_reg].b[3] -= src.b[3]; + cpu_state.MM[cpu_reg].b[4] -= src.b[4]; + cpu_state.MM[cpu_reg].b[5] -= src.b[5]; + cpu_state.MM[cpu_reg].b[6] -= src.b[6]; + cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - return 0; + return 0; } -static int opPADDD_a32(uint32_t fetchdat) +static int +opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + cpu_state.MM[cpu_reg].b[0] -= src.b[0]; + cpu_state.MM[cpu_reg].b[1] -= src.b[1]; + cpu_state.MM[cpu_reg].b[2] -= src.b[2]; + cpu_state.MM[cpu_reg].b[3] -= src.b[3]; + cpu_state.MM[cpu_reg].b[4] -= src.b[4]; + cpu_state.MM[cpu_reg].b[5] -= src.b[5]; + cpu_state.MM[cpu_reg].b[6] -= src.b[6]; + cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - return 0; + return 0; } -static int opPADDSB_a16(uint32_t fetchdat) +static int +opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + cpu_state.MM[cpu_reg].w[0] -= src.w[0]; + cpu_state.MM[cpu_reg].w[1] -= src.w[1]; + cpu_state.MM[cpu_reg].w[2] -= src.w[2]; + cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - return 0; + return 0; } -static int opPADDSB_a32(uint32_t fetchdat) +static int +opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + cpu_state.MM[cpu_reg].w[0] -= src.w[0]; + cpu_state.MM[cpu_reg].w[1] -= src.w[1]; + cpu_state.MM[cpu_reg].w[2] -= src.w[2]; + cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - return 0; + return 0; } -static int opPADDUSB_a16(uint32_t fetchdat) +static int +opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - return 0; + return 0; } -static int opPADDUSB_a32(uint32_t fetchdat) +static int +opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - return 0; + return 0; } -static int opPADDSW_a16(uint32_t fetchdat) +static int +opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + pclog("opPSUBSB_a16(%08X)\n", fetchdat); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - return 0; + return 0; } -static int opPADDSW_a32(uint32_t fetchdat) +static int +opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + pclog("opPSUBSB_a32(%08X)\n", fetchdat); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - return 0; + return 0; } -static int opPADDUSW_a16(uint32_t fetchdat) +static int +opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - return 0; + return 0; } -static int opPADDUSW_a32(uint32_t fetchdat) +static int +opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - return 0; + return 0; } -static int opPMADDWD_a16(uint32_t fetchdat) +static int +opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]); - - return 0; + return 0; } -static int opPMADDWD_a32(uint32_t fetchdat) +static int +opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]); - - return 0; + return 0; } - -static int opPMULLW_a16(uint32_t fetchdat) +static int +opPSUBUSW_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; + fetch_ea_16(fetchdat); + MMX_GETSRC(); - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } - return 0; + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + + return 0; } -static int opPMULLW_a32(uint32_t fetchdat) +static int +opPSUBUSW_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; + fetch_ea_32(fetchdat); + MMX_GETSRC(); - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } - return 0; -} - -static int opPMULHW_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } - return 0; -} -static int opPMULHW_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } - return 0; -} - -static int opPSUBB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - - return 0; -} -static int opPSUBB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - - return 0; -} - -static int opPSUBW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - - return 0; -} -static int opPSUBW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - - return 0; -} - -static int opPSUBD_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - - return 0; -} -static int opPSUBD_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - - return 0; -} - -static int opPSUBSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - pclog("opPSUBSB_a16(%08X)\n", fetchdat); - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - - return 0; -} -static int opPSUBSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - pclog("opPSUBSB_a32(%08X)\n", fetchdat); - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - - return 0; -} - -static int opPSUBUSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - - return 0; -} -static int opPSUBUSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - - return 0; -} - -static int opPSUBSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - - return 0; -} -static int opPSUBSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - - return 0; -} - -static int opPSUBUSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); - - return 0; -} -static int opPSUBUSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); - - return 0; + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + + return 0; } diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index a07d8d0a8..40ae66a9c 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -1,205 +1,217 @@ -static int opPCMPEQB_a16(uint32_t fetchdat) +static int +opPCMPEQB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPEQB_a32(uint32_t fetchdat) +static int +opPCMPEQB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPGTB_a16(uint32_t fetchdat) +static int +opPCMPGTB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPGTB_a32(uint32_t fetchdat) +static int +opPCMPGTB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPEQW_a16(uint32_t fetchdat) +static int +opPCMPEQW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPEQW_a32(uint32_t fetchdat) +static int +opPCMPEQW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPGTW_a16(uint32_t fetchdat) +static int +opPCMPGTW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPGTW_a32(uint32_t fetchdat) +static int +opPCMPGTW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPEQD_a16(uint32_t fetchdat) +static int +opPCMPEQD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; - return 0; + return 0; } -static int opPCMPEQD_a32(uint32_t fetchdat) +static int +opPCMPEQD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; - return 0; + return 0; } -static int opPCMPGTD_a16(uint32_t fetchdat) +static int +opPCMPGTD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; - return 0; + return 0; } -static int opPCMPGTD_a32(uint32_t fetchdat) +static int +opPCMPGTD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; - return 0; + return 0; } diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index e3f1d9145..c22c820c1 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -1,91 +1,99 @@ -static int opPAND_a16(uint32_t fetchdat) +static int +opPAND_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; - return 0; + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } -static int opPAND_a32(uint32_t fetchdat) +static int +opPAND_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; - return 0; + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } -static int opPANDN_a16(uint32_t fetchdat) +static int +opPANDN_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; + cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + return 0; } -static int opPANDN_a32(uint32_t fetchdat) +static int +opPANDN_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; + cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + return 0; } -static int opPOR_a16(uint32_t fetchdat) +static int +opPOR_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; - return 0; + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } -static int opPOR_a32(uint32_t fetchdat) +static int +opPOR_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; - return 0; + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } -static int opPXOR_a16(uint32_t fetchdat) +static int +opPXOR_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } -static int opPXOR_a32(uint32_t fetchdat) +static int +opPXOR_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index fe06525b7..bb51573e6 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -1,217 +1,217 @@ -static int opMOVD_l_mm_a16(uint32_t fetchdat) +static int +opMOVD_l_mm_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } - else - { - uint32_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(1); + } else { + uint32_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_l_mm_a32(uint32_t fetchdat) +static int +opMOVD_l_mm_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } - else - { - uint32_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(1); + } else { + uint32_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_mm_l_a16(uint32_t fetchdat) +static int +opMOVD_mm_l_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_mm_l_a32(uint32_t fetchdat) +static int +opMOVD_mm_l_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) /*Cyrix maps both MOVD and SMINT to the same opcode*/ -static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) +static int +opMOVD_mm_l_a16_cx(uint32_t fetchdat) { - if (in_smm) - return opSMINT(fetchdat); + if (in_smm) + return opSMINT(fetchdat); - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_mm_l_a32_cx(uint32_t fetchdat) +static int +opMOVD_mm_l_a32_cx(uint32_t fetchdat) { - if (in_smm) - return opSMINT(fetchdat); + if (in_smm) + return opSMINT(fetchdat); - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } #endif -static int opMOVQ_q_mm_a16(uint32_t fetchdat) +static int +opMOVQ_q_mm_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } - else - { - uint64_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + CLOCK_CYCLES(1); + } else { + uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVQ_q_mm_a32(uint32_t fetchdat) +static int +opMOVQ_q_mm_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } - else - { - uint64_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + CLOCK_CYCLES(1); + } else { + uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVQ_mm_q_a16(uint32_t fetchdat) +static int +opMOVQ_mm_q_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVQ_mm_q_a32(uint32_t fetchdat) +static int +opMOVQ_mm_q_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index e12d1b448..f0180db91 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -1,326 +1,342 @@ -static int opPUNPCKLDQ_a16(uint32_t fetchdat) +static int +opPUNPCKLDQ_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } - else - { - uint32_t src; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + CLOCK_CYCLES(1); + } else { + uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = src; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opPUNPCKLDQ_a32(uint32_t fetchdat) +static int +opPUNPCKLDQ_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } - else - { - uint32_t src; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + CLOCK_CYCLES(1); + } else { + uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = src; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opPUNPCKHDQ_a16(uint32_t fetchdat) +static int +opPUNPCKHDQ_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; + cpu_state.MM[cpu_reg].l[1] = src.l[1]; - return 0; + return 0; } -static int opPUNPCKHDQ_a32(uint32_t fetchdat) +static int +opPUNPCKHDQ_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; + cpu_state.MM[cpu_reg].l[1] = src.l[1]; - return 0; + return 0; } -static int opPUNPCKLBW_a16(uint32_t fetchdat) +static int +opPUNPCKLBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + cpu_state.MM[cpu_reg].b[7] = src.b[3]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; + cpu_state.MM[cpu_reg].b[5] = src.b[2]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; + cpu_state.MM[cpu_reg].b[3] = src.b[1]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; + cpu_state.MM[cpu_reg].b[1] = src.b[0]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - return 0; + return 0; } -static int opPUNPCKLBW_a32(uint32_t fetchdat) +static int +opPUNPCKLBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + cpu_state.MM[cpu_reg].b[7] = src.b[3]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; + cpu_state.MM[cpu_reg].b[5] = src.b[2]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; + cpu_state.MM[cpu_reg].b[3] = src.b[1]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; + cpu_state.MM[cpu_reg].b[1] = src.b[0]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - return 0; + return 0; } -static int opPUNPCKHBW_a16(uint32_t fetchdat) +static int +opPUNPCKHBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; + cpu_state.MM[cpu_reg].b[1] = src.b[4]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; + cpu_state.MM[cpu_reg].b[3] = src.b[5]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; + cpu_state.MM[cpu_reg].b[5] = src.b[6]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; + cpu_state.MM[cpu_reg].b[7] = src.b[7]; - return 0; + return 0; } -static int opPUNPCKHBW_a32(uint32_t fetchdat) +static int +opPUNPCKHBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; + cpu_state.MM[cpu_reg].b[1] = src.b[4]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; + cpu_state.MM[cpu_reg].b[3] = src.b[5]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; + cpu_state.MM[cpu_reg].b[5] = src.b[6]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; + cpu_state.MM[cpu_reg].b[7] = src.b[7]; - return 0; + return 0; } -static int opPUNPCKLWD_a16(uint32_t fetchdat) +static int +opPUNPCKLWD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + cpu_state.MM[cpu_reg].w[3] = src.w[1]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; + cpu_state.MM[cpu_reg].w[1] = src.w[0]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - return 0; + return 0; } -static int opPUNPCKLWD_a32(uint32_t fetchdat) +static int +opPUNPCKLWD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + cpu_state.MM[cpu_reg].w[3] = src.w[1]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; + cpu_state.MM[cpu_reg].w[1] = src.w[0]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - return 0; + return 0; } -static int opPUNPCKHWD_a16(uint32_t fetchdat) +static int +opPUNPCKHWD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; + cpu_state.MM[cpu_reg].w[1] = src.w[2]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; + cpu_state.MM[cpu_reg].w[3] = src.w[3]; - return 0; + return 0; } -static int opPUNPCKHWD_a32(uint32_t fetchdat) +static int +opPUNPCKHWD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; + cpu_state.MM[cpu_reg].w[1] = src.w[2]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; + cpu_state.MM[cpu_reg].w[3] = src.w[3]; - return 0; + return 0; } -static int opPACKSSWB_a16(uint32_t fetchdat) +static int +opPACKSSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_16(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); - return 0; + return 0; } -static int opPACKSSWB_a32(uint32_t fetchdat) +static int +opPACKSSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_32(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); - return 0; + return 0; } -static int opPACKUSWB_a16(uint32_t fetchdat) +static int +opPACKUSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_16(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); + cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); + cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); + cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); - return 0; + return 0; } -static int opPACKUSWB_a32(uint32_t fetchdat) +static int +opPACKUSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_32(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); + cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); + cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); + cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); - return 0; + return 0; } -static int opPACKSSDW_a16(uint32_t fetchdat) +static int +opPACKSSDW_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_16(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); - return 0; + return 0; } -static int opPACKSSDW_a32(uint32_t fetchdat) +static int +opPACKSSDW_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_32(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); - return 0; + return 0; } diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index df8d75cf8..c9ddc9b93 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -1,450 +1,453 @@ -#define MMX_GETSHIFT() \ - if (cpu_mod == 3) \ - { \ - shift = cpu_state.MM[cpu_rm].b[0]; \ - CLOCK_CYCLES(1); \ - } \ - else \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ - CLOCK_CYCLES(2); \ - } +#define MMX_GETSHIFT() \ + if (cpu_mod == 3) { \ + shift = cpu_state.MM[cpu_rm].b[0]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + shift = readmemb(easeg, cpu_state.eaaddr); \ + if (cpu_state.abrt) \ + return 0; \ + CLOCK_CYCLES(2); \ + } -static int opPSxxW_imm(uint32_t fetchdat) +static int +opPSxxW_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; - cpu_state.pc += 2; - MMX_ENTER(); + cpu_state.pc += 2; + MMX_ENTER(); - switch (op) - { - case 0x10: /*PSRLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].w[0] >>= shift; - cpu_state.MM[reg].w[1] >>= shift; - cpu_state.MM[reg].w[2] >>= shift; - cpu_state.MM[reg].w[3] >>= shift; - } - break; - case 0x20: /*PSRAW*/ - if (shift > 15) - shift = 15; - cpu_state.MM[reg].sw[0] >>= shift; - cpu_state.MM[reg].sw[1] >>= shift; - cpu_state.MM[reg].sw[2] >>= shift; - cpu_state.MM[reg].sw[3] >>= shift; - break; - case 0x30: /*PSLLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].w[0] <<= shift; - cpu_state.MM[reg].w[1] <<= shift; - cpu_state.MM[reg].w[2] <<= shift; - cpu_state.MM[reg].w[3] <<= shift; - } - break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } - - CLOCK_CYCLES(1); - return 0; -} - -static int opPSLLW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } - - return 0; -} -static int opPSLLW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } - - return 0; -} - -static int opPSRLW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } - - return 0; -} -static int opPSRLW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } - - return 0; -} - -static int opPSRAW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) + switch (op) { + case 0x10: /*PSRLW*/ + if (shift > 15) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].w[0] >>= shift; + cpu_state.MM[reg].w[1] >>= shift; + cpu_state.MM[reg].w[2] >>= shift; + cpu_state.MM[reg].w[3] >>= shift; + } + break; + case 0x20: /*PSRAW*/ + if (shift > 15) shift = 15; + cpu_state.MM[reg].sw[0] >>= shift; + cpu_state.MM[reg].sw[1] >>= shift; + cpu_state.MM[reg].sw[2] >>= shift; + cpu_state.MM[reg].sw[3] >>= shift; + break; + case 0x30: /*PSLLW*/ + if (shift > 15) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].w[0] <<= shift; + cpu_state.MM[reg].w[1] <<= shift; + cpu_state.MM[reg].w[2] <<= shift; + cpu_state.MM[reg].w[3] <<= shift; + } + break; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 0; + } - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; - - return 0; -} -static int opPSRAW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - shift = 15; - - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; - - return 0; + CLOCK_CYCLES(1); + return 0; } -static int opPSxxD_imm(uint32_t fetchdat) +static int +opPSLLW_a16(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int shift; - cpu_state.pc += 2; - MMX_ENTER(); + MMX_ENTER(); - switch (op) - { - case 0x10: /*PSRLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].l[0] >>= shift; - cpu_state.MM[reg].l[1] >>= shift; - } - break; - case 0x20: /*PSRAD*/ - if (shift > 31) - shift = 31; - cpu_state.MM[reg].sl[0] >>= shift; - cpu_state.MM[reg].sl[1] >>= shift; - break; - case 0x30: /*PSLLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].l[0] <<= shift; - cpu_state.MM[reg].l[1] <<= shift; - } - break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - CLOCK_CYCLES(1); - return 0; + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] <<= shift; + cpu_state.MM[cpu_reg].w[1] <<= shift; + cpu_state.MM[cpu_reg].w[2] <<= shift; + cpu_state.MM[cpu_reg].w[3] <<= shift; + } + + return 0; +} +static int +opPSLLW_a32(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); + + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] <<= shift; + cpu_state.MM[cpu_reg].w[1] <<= shift; + cpu_state.MM[cpu_reg].w[2] <<= shift; + cpu_state.MM[cpu_reg].w[3] <<= shift; + } + + return 0; } -static int opPSLLD_a16(uint32_t fetchdat) +static int +opPSRLW_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] >>= shift; + cpu_state.MM[cpu_reg].w[1] >>= shift; + cpu_state.MM[cpu_reg].w[2] >>= shift; + cpu_state.MM[cpu_reg].w[3] >>= shift; + } - return 0; + return 0; } -static int opPSLLD_a32(uint32_t fetchdat) +static int +opPSRLW_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] >>= shift; + cpu_state.MM[cpu_reg].w[1] >>= shift; + cpu_state.MM[cpu_reg].w[2] >>= shift; + cpu_state.MM[cpu_reg].w[3] >>= shift; + } - return 0; + return 0; } -static int opPSRLD_a16(uint32_t fetchdat) +static int +opPSRAW_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } + if (shift > 15) + shift = 15; - return 0; + cpu_state.MM[cpu_reg].sw[0] >>= shift; + cpu_state.MM[cpu_reg].sw[1] >>= shift; + cpu_state.MM[cpu_reg].sw[2] >>= shift; + cpu_state.MM[cpu_reg].sw[3] >>= shift; + + return 0; } -static int opPSRLD_a32(uint32_t fetchdat) +static int +opPSRAW_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } + if (shift > 15) + shift = 15; - return 0; + cpu_state.MM[cpu_reg].sw[0] >>= shift; + cpu_state.MM[cpu_reg].sw[1] >>= shift; + cpu_state.MM[cpu_reg].sw[2] >>= shift; + cpu_state.MM[cpu_reg].sw[3] >>= shift; + + return 0; } -static int opPSRAD_a16(uint32_t fetchdat) +static int +opPSxxD_imm(uint32_t fetchdat) { - int shift; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; - MMX_ENTER(); + cpu_state.pc += 2; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 31) + switch (op) { + case 0x10: /*PSRLD*/ + if (shift > 31) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].l[0] >>= shift; + cpu_state.MM[reg].l[1] >>= shift; + } + break; + case 0x20: /*PSRAD*/ + if (shift > 31) shift = 31; + cpu_state.MM[reg].sl[0] >>= shift; + cpu_state.MM[reg].sl[1] >>= shift; + break; + case 0x30: /*PSLLD*/ + if (shift > 31) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].l[0] <<= shift; + cpu_state.MM[reg].l[1] <<= shift; + } + break; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 0; + } - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; - - return 0; + CLOCK_CYCLES(1); + return 0; } -static int opPSRAD_a32(uint32_t fetchdat) + +static int +opPSLLD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - shift = 31; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] <<= shift; + cpu_state.MM[cpu_reg].l[1] <<= shift; + } - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; - - return 0; + return 0; } - -static int opPSxxQ_imm(uint32_t fetchdat) +static int +opPSLLD_a32(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int shift; - cpu_state.pc += 2; - MMX_ENTER(); + MMX_ENTER(); - switch (op) - { - case 0x10: /*PSRLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q >>= shift; - break; - case 0x20: /*PSRAW*/ - if (shift > 63) - shift = 63; - cpu_state.MM[reg].sq >>= shift; - break; - case 0x30: /*PSLLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q <<= shift; - break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - CLOCK_CYCLES(1); - return 0; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] <<= shift; + cpu_state.MM[cpu_reg].l[1] <<= shift; + } + + return 0; } -static int opPSLLQ_a16(uint32_t fetchdat) +static int +opPSRLD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] >>= shift; + cpu_state.MM[cpu_reg].l[1] >>= shift; + } - return 0; + return 0; } -static int opPSLLQ_a32(uint32_t fetchdat) +static int +opPSRLD_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] >>= shift; + cpu_state.MM[cpu_reg].l[1] >>= shift; + } - return 0; + return 0; } -static int opPSRLQ_a16(uint32_t fetchdat) +static int +opPSRAD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + if (shift > 31) + shift = 31; - return 0; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; + + return 0; } -static int opPSRLQ_a32(uint32_t fetchdat) +static int +opPSRAD_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + if (shift > 31) + shift = 31; - return 0; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; + + return 0; +} + +static int +opPSxxQ_imm(uint32_t fetchdat) +{ + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; + + cpu_state.pc += 2; + MMX_ENTER(); + + switch (op) { + case 0x10: /*PSRLW*/ + if (shift > 63) + cpu_state.MM[reg].q = 0; + else + cpu_state.MM[reg].q >>= shift; + break; + case 0x20: /*PSRAW*/ + if (shift > 63) + shift = 63; + cpu_state.MM[reg].sq >>= shift; + break; + case 0x30: /*PSLLW*/ + if (shift > 63) + cpu_state.MM[reg].q = 0; + else + cpu_state.MM[reg].q <<= shift; + break; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 0; + } + + CLOCK_CYCLES(1); + return 0; +} + +static int +opPSLLQ_a16(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; + + return 0; +} +static int +opPSLLQ_a32(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; + + return 0; +} + +static int +opPSRLQ_a16(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; + + return 0; +} +static int +opPSRLQ_a32(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; + + return 0; } diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index e7d5247d1..063a33516 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -1,771 +1,853 @@ -static int opMOV_AL_imm(uint32_t fetchdat) +static int +opMOV_AL_imm(uint32_t fetchdat) { - AL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + AL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_AH_imm(uint32_t fetchdat) +static int +opMOV_AH_imm(uint32_t fetchdat) { - AH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + AH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BL_imm(uint32_t fetchdat) +static int +opMOV_BL_imm(uint32_t fetchdat) { - BL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + BL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BH_imm(uint32_t fetchdat) +static int +opMOV_BH_imm(uint32_t fetchdat) { - BH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + BH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CL_imm(uint32_t fetchdat) +static int +opMOV_CL_imm(uint32_t fetchdat) { - CL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + CL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CH_imm(uint32_t fetchdat) +static int +opMOV_CH_imm(uint32_t fetchdat) { - CH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + CH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DL_imm(uint32_t fetchdat) +static int +opMOV_DL_imm(uint32_t fetchdat) { - DL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + DL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DH_imm(uint32_t fetchdat) +static int +opMOV_DH_imm(uint32_t fetchdat) { - DH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + DH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_AX_imm(uint32_t fetchdat) +static int +opMOV_AX_imm(uint32_t fetchdat) { - AX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + AX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BX_imm(uint32_t fetchdat) +static int +opMOV_BX_imm(uint32_t fetchdat) { - BX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + BX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CX_imm(uint32_t fetchdat) +static int +opMOV_CX_imm(uint32_t fetchdat) { - CX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + CX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DX_imm(uint32_t fetchdat) +static int +opMOV_DX_imm(uint32_t fetchdat) { - DX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + DX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_SI_imm(uint32_t fetchdat) +static int +opMOV_SI_imm(uint32_t fetchdat) { - SI = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + SI = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DI_imm(uint32_t fetchdat) +static int +opMOV_DI_imm(uint32_t fetchdat) { - DI = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + DI = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BP_imm(uint32_t fetchdat) +static int +opMOV_BP_imm(uint32_t fetchdat) { - BP = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + BP = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_SP_imm(uint32_t fetchdat) +static int +opMOV_SP_imm(uint32_t fetchdat) { - SP = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + SP = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EAX_imm(uint32_t fetchdat) +static int +opMOV_EAX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EAX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EAX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EBX_imm(uint32_t fetchdat) +static int +opMOV_EBX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EBX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EBX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_ECX_imm(uint32_t fetchdat) +static int +opMOV_ECX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ECX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + ECX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EDX_imm(uint32_t fetchdat) +static int +opMOV_EDX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EDX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EDX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_ESI_imm(uint32_t fetchdat) +static int +opMOV_ESI_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ESI = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + ESI = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EDI_imm(uint32_t fetchdat) +static int +opMOV_EDI_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EDI = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EDI = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EBP_imm(uint32_t fetchdat) +static int +opMOV_EBP_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EBP = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EBP = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_ESP_imm(uint32_t fetchdat) +static int +opMOV_ESP_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ESP = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + ESP = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_b_imm_a16(uint32_t fetchdat) +static int +opMOV_b_imm_a16(uint32_t fetchdat) { - uint8_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); + uint8_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = readmemb(cs, cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + seteab(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_b_imm_a32(uint32_t fetchdat) +{ + uint8_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getbyte(); + if (cpu_state.abrt) + return 1; + seteab(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 1); + return cpu_state.abrt; +} + +static int +opMOV_w_imm_a16(uint32_t fetchdat) +{ + uint16_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getword(); + if (cpu_state.abrt) + return 1; + seteaw(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 4, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_w_imm_a32(uint32_t fetchdat) +{ + uint16_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getword(); + if (cpu_state.abrt) + return 1; + seteaw(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 4, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 1); + return cpu_state.abrt; +} +static int +opMOV_l_imm_a16(uint32_t fetchdat) +{ + uint32_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getlong(); + if (cpu_state.abrt) + return 1; + seteal(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 6, rmdat, 0, 0, 0, (cpu_mod == 3) ? 1 : 0, 0); + return cpu_state.abrt; +} +static int +opMOV_l_imm_a32(uint32_t fetchdat) +{ + uint32_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getlong(); + if (cpu_state.abrt) + return 1; + seteal(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 6, rmdat, 0, 0, 0, (cpu_mod == 3) ? 1 : 0, 1); + return cpu_state.abrt; +} + +static int +opMOV_AL_a16(uint32_t fetchdat) +{ + uint8_t temp; + uint16_t addr = getwordf(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 3, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opMOV_AL_a32(uint32_t fetchdat) +{ + uint8_t temp; + uint32_t addr = getlong(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 5, -1, 1, 0, 0, 0, 1); + return 0; +} +static int +opMOV_AX_a16(uint32_t fetchdat) +{ + uint16_t temp; + uint16_t addr = getwordf(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 1UL); + temp = readmemw(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 3, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opMOV_AX_a32(uint32_t fetchdat) +{ + uint16_t temp; + uint32_t addr = getlong(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 1); + temp = readmemw(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 5, -1, 1, 0, 0, 0, 1); + return 0; +} +static int +opMOV_EAX_a16(uint32_t fetchdat) +{ + uint32_t temp; + uint16_t addr = getwordf(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 3UL); + temp = readmeml(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + EAX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 3, -1, 0, 1, 0, 0, 0); + return 0; +} +static int +opMOV_EAX_a32(uint32_t fetchdat) +{ + uint32_t temp; + uint32_t addr = getlong(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 3); + temp = readmeml(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + EAX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 5, -1, 0, 1, 0, 0, 1); + return 0; +} + +static int +opMOV_a16_AL(uint32_t fetchdat) +{ + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); + writememb(cpu_state.ea_seg->base, addr, AL); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_a32_AL(uint32_t fetchdat) +{ + uint32_t addr = getlong(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); + writememb(cpu_state.ea_seg->base, addr, AL); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 5, -1, 0, 0, 1, 0, 1); + return cpu_state.abrt; +} +static int +opMOV_a16_AX(uint32_t fetchdat) +{ + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1UL); + writememw(cpu_state.ea_seg->base, addr, AX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_a32_AX(uint32_t fetchdat) +{ + uint32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); + writememw(cpu_state.ea_seg->base, addr, AX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 5, -1, 0, 0, 1, 0, 1); + return cpu_state.abrt; +} +static int +opMOV_a16_EAX(uint32_t fetchdat) +{ + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3UL); + writememl(cpu_state.ea_seg->base, addr, EAX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 3, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; +} +static int +opMOV_a32_EAX(uint32_t fetchdat) +{ + uint32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); + writememl(cpu_state.ea_seg->base, addr, EAX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 5, -1, 0, 0, 0, 1, 1); + return cpu_state.abrt; +} + +static int +opLEA_w_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opLEA_w_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opLEA_l_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].l = cpu_state.eaaddr & 0xffff; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opLEA_l_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].l = cpu_state.eaaddr; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opXLAT_a16(uint32_t fetchdat) +{ + uint32_t addr = (BX + AL) & 0xFFFF; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opXLAT_a32(uint32_t fetchdat) +{ + uint32_t addr = EBX + AL; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_b_r_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_rm, getr8(cpu_reg)); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = readmemb(cs,cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - seteab(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); - return cpu_state.abrt; + seteab(getr8(cpu_reg)); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 0); + } + return cpu_state.abrt; } -static int opMOV_b_imm_a32(uint32_t fetchdat) +static int +opMOV_b_r_a32(uint32_t fetchdat) { - uint8_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getbyte(); if (cpu_state.abrt) return 1; - seteab(temp); + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_rm, getr8(cpu_reg)); CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); - return cpu_state.abrt; + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(getr8(cpu_reg)); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 1); + } + return cpu_state.abrt; +} +static int +opMOV_w_r_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.regs[cpu_reg].w); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 0); + } + return cpu_state.abrt; +} +static int +opMOV_w_r_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.regs[cpu_reg].w); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 1); + } + return cpu_state.abrt; +} +static int +opMOV_l_r_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(cpu_state.regs[cpu_reg].l); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 0, 1, 0); + } + return cpu_state.abrt; +} +static int +opMOV_l_r_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(cpu_state.regs[cpu_reg].l); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 0, 1, 1); + } + return cpu_state.abrt; } -static int opMOV_w_imm_a16(uint32_t fetchdat) +static int +opMOV_r_b_a16(uint32_t fetchdat) { + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_reg, getr8(cpu_rm)); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { + uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + temp = geteab(); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 0); + } + return 0; +} +static int +opMOV_r_b_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_reg, getr8(cpu_rm)); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + temp = geteab(); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 1); + } + return 0; +} +static int +opMOV_r_w_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { uint16_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getword(); if (cpu_state.abrt) return 1; - seteaw(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); - return cpu_state.abrt; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 0); + } + return 0; } -static int opMOV_w_imm_a32(uint32_t fetchdat) +static int +opMOV_r_w_a32(uint32_t fetchdat) { + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { uint16_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getword(); if (cpu_state.abrt) return 1; - seteaw(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); - return cpu_state.abrt; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 1); + } + return 0; } -static int opMOV_l_imm_a16(uint32_t fetchdat) +static int +opMOV_r_l_a16(uint32_t fetchdat) { + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { uint32_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getlong(); if (cpu_state.abrt) return 1; - seteal(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 0); - return cpu_state.abrt; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + temp = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 0, 1, 0, 0, 0); + } + return 0; } -static int opMOV_l_imm_a32(uint32_t fetchdat) +static int +opMOV_r_l_a32(uint32_t fetchdat) { + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { uint32_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getlong(); if (cpu_state.abrt) return 1; - seteal(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 1); - return cpu_state.abrt; -} - - -static int opMOV_AL_a16(uint32_t fetchdat) -{ - uint8_t temp; - uint16_t addr = getwordf(); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); - return 0; -} -static int opMOV_AL_a32(uint32_t fetchdat) -{ - uint8_t temp; - uint32_t addr = getlong(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); - return 0; -} -static int opMOV_AX_a16(uint32_t fetchdat) -{ - uint16_t temp; - uint16_t addr = getwordf(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr + 1UL); - temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); - return 0; -} -static int opMOV_AX_a32(uint32_t fetchdat) -{ - uint16_t temp; - uint32_t addr = getlong(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+1); - temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); - return 0; -} -static int opMOV_EAX_a16(uint32_t fetchdat) -{ - uint32_t temp; - uint16_t addr = getwordf(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr + 3UL); - temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - EAX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 0,1,0,0, 0); - return 0; -} -static int opMOV_EAX_a32(uint32_t fetchdat) -{ - uint32_t temp; - uint32_t addr = getlong(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+3); - temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - EAX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 0,1,0,0, 1); - return 0; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + temp = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 0, 1, 0, 0, 1); + } + return 0; } -static int opMOV_a16_AL(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); - writememb(cpu_state.ea_seg->base, addr, AL); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opMOV_a32_AL(uint32_t fetchdat) -{ - uint32_t addr = getlong(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); - writememb(cpu_state.ea_seg->base, addr, AL); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); - return cpu_state.abrt; -} -static int opMOV_a16_AX(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1UL); - writememw(cpu_state.ea_seg->base, addr, AX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opMOV_a32_AX(uint32_t fetchdat) -{ - uint32_t addr = getlong(); if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); - writememw(cpu_state.ea_seg->base, addr, AX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); - return cpu_state.abrt; -} -static int opMOV_a16_EAX(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3UL); - writememl(cpu_state.ea_seg->base, addr, EAX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} -static int opMOV_a32_EAX(uint32_t fetchdat) -{ - uint32_t addr = getlong(); if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); - writememl(cpu_state.ea_seg->base, addr, EAX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,0,1, 1); - return cpu_state.abrt; -} - - -static int opLEA_w_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opLEA_w_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opLEA_l_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].l = cpu_state.eaaddr & 0xffff; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opLEA_l_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].l = cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - return 0; -} - - - -static int opXLAT_a16(uint32_t fetchdat) -{ - uint32_t addr = (BX + AL)&0xFFFF; - uint8_t temp; - - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; -} -static int opXLAT_a32(uint32_t fetchdat) -{ - uint32_t addr = EBX + AL; - uint8_t temp; - - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; -} - -static int opMOV_b_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_rm, getr8(cpu_reg)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(getr8(cpu_reg)); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); - } - return cpu_state.abrt; -} -static int opMOV_b_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_rm, getr8(cpu_reg)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(getr8(cpu_reg)); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); - } - return cpu_state.abrt; -} -static int opMOV_w_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.regs[cpu_reg].w); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); - } - return cpu_state.abrt; -} -static int opMOV_w_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.regs[cpu_reg].w); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); - } - return cpu_state.abrt; -} -static int opMOV_l_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(cpu_state.regs[cpu_reg].l); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 0); - } - return cpu_state.abrt; -} -static int opMOV_l_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(cpu_state.regs[cpu_reg].l); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 1); - } - return cpu_state.abrt; -} - -static int opMOV_r_b_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_reg, getr8(cpu_rm)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - temp = geteab(); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 0); - } - return 0; -} -static int opMOV_r_b_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_reg, getr8(cpu_rm)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - temp = geteab(); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 1); - } - return 0; -} -static int opMOV_r_w_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 0); - } - return 0; -} -static int opMOV_r_w_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 1); - } - return 0; -} -static int opMOV_r_l_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - temp = geteal(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 0,1,0,0, 0); - } - return 0; -} -static int opMOV_r_l_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - temp = geteal(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 0,1,0,0, 1); - } - return 0; -} - -#define opCMOV(condition) \ - static int opCMOV ## condition ## _w_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _w_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _l_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else \ - { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _l_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else \ - { \ - uint32_t temp; \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } +#define opCMOV(condition) \ + static int opCMOV##condition##_w_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_w_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } +// clang-format off opCMOV(O) opCMOV(NO) opCMOV(B) @@ -782,3 +864,4 @@ opCMOV(L) opCMOV(NL) opCMOV(LE) opCMOV(NLE) +// clang-format on diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 0d973338e..d28033d5d 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -1,368 +1,362 @@ -static int opMOV_r_CRx_a16(uint32_t fetchdat) +static int +opMOV_r_CRx_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - switch (cpu_reg) - { - case 0: - cpu_state.regs[cpu_rm].l = cr0; - if (is486 || isibm486) - cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ - else { - if (is386) - cpu_state.regs[cpu_rm].l |=0x7fffffe0; - else - cpu_state.regs[cpu_rm].l |=0x7ffffff0; - } - break; - case 2: - cpu_state.regs[cpu_rm].l = cr2; - break; - case 3: - cpu_state.regs[cpu_rm].l = cr3; - break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - cpu_state.regs[cpu_rm].l = cr4; - break; - } - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_CRx_a32(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - switch (cpu_reg) - { - case 0: - cpu_state.regs[cpu_rm].l = cr0; - if (is486 || isibm486) - cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ - else { - if (is386) - cpu_state.regs[cpu_rm].l |=0x7fffffe0; - else - cpu_state.regs[cpu_rm].l |=0x7ffffff0; - } - break; - case 2: - cpu_state.regs[cpu_rm].l = cr2; - break; - case 3: - cpu_state.regs[cpu_rm].l = cr3; - break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - cpu_state.regs[cpu_rm].l = cr4; - break; - } - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_r_DRx_a16(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_DRx_a32(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_CRx_r_a16(uint32_t fetchdat) -{ - uint32_t old_cr0 = cr0; - - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - fetch_ea_16(fetchdat); - switch (cpu_reg) - { - case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) - flushmmucache(); - /* Make sure CPL = 0 when switching from real mode to protected mode. */ - if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) - cpu_state.seg_cs.access &= 0x9f; - cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) - cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm=4; - if (hascache && !(cr0 & (1 << 30))) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) - cpu_update_waitstates(); - if (cr0 & 1) - cpu_cur_status |= CPU_STATUS_PMODE; + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; else - cpu_cur_status &= ~CPU_STATUS_PMODE; + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; break; - case 2: - cr2 = cpu_state.regs[cpu_rm].l; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_CRx_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; + else + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; break; - case 3: - cr3 = cpu_state.regs[cpu_rm].l; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_r_DRx_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_DRx_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_CRx_r_a16(uint32_t fetchdat) +{ + uint32_t old_cr0 = cr0; + + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) - flushmmucache(); - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; - break; - } + } - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CRx_r_a32(uint32_t fetchdat) +static int +opMOV_CRx_r_a32(uint32_t fetchdat) { - uint32_t old_cr0 = cr0; + uint32_t old_cr0 = cr0; - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - fetch_ea_32(fetchdat); - switch (cpu_reg) - { - case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) - flushmmucache(); - /* Make sure CPL = 0 when switching from real mode to protected mode. */ - if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) - cpu_state.seg_cs.access &= 0x9f; - cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) - cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm=4; - if (hascache && !(cr0 & (1 << 30))) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) - cpu_update_waitstates(); - if (cr0 & 1) - cpu_cur_status |= CPU_STATUS_PMODE; - else - cpu_cur_status &= ~CPU_STATUS_PMODE; - break; - case 2: - cr2 = cpu_state.regs[cpu_rm].l; - break; - case 3: - cr3 = cpu_state.regs[cpu_rm].l; + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) - flushmmucache(); - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; + } + + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_DRx_r_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_DRx_r_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static void +opMOV_r_TRx(void) +{ + uint32_t base; + + base = _tr[4] & 0xfffff800; + switch (cpu_reg) { + case 3: + pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); + _tr[3] = *(uint32_t *) &(_cache[cache_index]); + cache_index = (cache_index + 4) & 0xf; + break; + } + cpu_state.regs[cpu_rm].l = _tr[cpu_reg]; + CLOCK_CYCLES(6); +} +static int +opMOV_r_TRx_a16(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_TRx_a32(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static void +opMOV_TRx_r(void) +{ + uint32_t base; + int i, ctl; + + _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; + base = _tr[4] & 0xfffff800; + ctl = _tr[5] & 3; + switch (cpu_reg) { + case 3: + pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); + *(uint32_t *) &(_cache[cache_index]) = _tr[3]; + cache_index = (cache_index + 4) & 0xf; + break; + case 4: + if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) + pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); + break; + case 5: + pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); + if (!(_tr[5] & (1 << 19))) { + switch (ctl) { + case 0: + pclog(" Cache fill or read...\n", base); + break; + case 1: + base += (_tr[5] & 0x7f0); + pclog(" Writing 16 bytes to %08X...\n", base); + for (i = 0; i < 16; i += 4) + mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); + break; + case 2: + base += (_tr[5] & 0x7f0); + pclog(" Reading 16 bytes from %08X...\n", base); + for (i = 0; i < 16; i += 4) + *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); + break; + case 3: + pclog(" Cache invalidate/flush...\n", base); break; } - - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 1); - return 0; + } + break; + } + CLOCK_CYCLES(6); } - -static int opMOV_DRx_r_a16(uint32_t fetchdat) +static int +opMOV_TRx_r_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DRx_r_a32(uint32_t fetchdat) +static int +opMOV_TRx_r_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static void opMOV_r_TRx(void) -{ - uint32_t base; - - base = _tr[4] & 0xfffff800; - switch (cpu_reg) { - case 3: - pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); - _tr[3] = *(uint32_t *) &(_cache[cache_index]); - cache_index = (cache_index + 4) & 0xf; - break; - } - cpu_state.regs[cpu_rm].l = _tr[cpu_reg]; - CLOCK_CYCLES(6); -} -static int opMOV_r_TRx_a16(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - opMOV_r_TRx(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_TRx_a32(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - opMOV_r_TRx(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static void opMOV_TRx_r(void) -{ - uint32_t base; - int i, ctl; - - _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; - base = _tr[4] & 0xfffff800; - ctl = _tr[5] & 3; - switch (cpu_reg) { - case 3: - pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); - *(uint32_t *) &(_cache[cache_index]) = _tr[3]; - cache_index = (cache_index + 4) & 0xf; - break; - case 4: - if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) - pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); - break; - case 5: - pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); - if (!(_tr[5] & (1 << 19))) { - switch(ctl) { - case 0: - pclog(" Cache fill or read...\n", base); - break; - case 1: - base += (_tr[5] & 0x7f0); - pclog(" Writing 16 bytes to %08X...\n", base); - for (i = 0; i < 16; i += 4) - mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); - break; - case 2: - base += (_tr[5] & 0x7f0); - pclog(" Reading 16 bytes from %08X...\n", base); - for (i = 0; i < 16; i += 4) - *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); - break; - case 3: - pclog(" Cache invalidate/flush...\n", base); - break; - } - } - break; - } - CLOCK_CYCLES(6); -} -static int opMOV_TRx_r_a16(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - opMOV_TRx_r(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_TRx_r_a32(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - opMOV_TRx_r(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index 02e2d50de..c6bfd9933 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -1,446 +1,535 @@ -static int opMOV_w_seg_a16(uint32_t fetchdat) +static int +opMOV_w_seg_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + seteaw(ES); + break; + case 0x08: /*CS*/ + seteaw(CS); + break; + case 0x18: /*DS*/ + seteaw(DS); + break; + case 0x10: /*SS*/ + seteaw(SS); + break; + case 0x20: /*FS*/ + seteaw(FS); + break; + case 0x28: /*GS*/ + seteaw(GS); + break; + } + + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_w_seg_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + seteaw(ES); + break; + case 0x08: /*CS*/ + seteaw(CS); + break; + case 0x18: /*DS*/ + seteaw(DS); + break; + case 0x10: /*SS*/ + seteaw(SS); + break; + case 0x20: /*FS*/ + seteaw(FS); + break; + case 0x28: /*GS*/ + seteaw(GS); + break; + } + + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return cpu_state.abrt; +} + +static int +opMOV_l_seg_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = ES; + else seteaw(ES); - break; - case 0x08: /*CS*/ + break; + case 0x08: /*CS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = CS; + else seteaw(CS); - break; - case 0x18: /*DS*/ + break; + case 0x18: /*DS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = DS; + else seteaw(DS); - break; - case 0x10: /*SS*/ + break; + case 0x10: /*SS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = SS; + else seteaw(SS); - break; - case 0x20: /*FS*/ + break; + case 0x20: /*FS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = FS; + else seteaw(FS); - break; - case 0x28: /*GS*/ + break; + case 0x28: /*GS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = GS; + else seteaw(GS); - break; - } + break; + } - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return cpu_state.abrt; } -static int opMOV_w_seg_a32(uint32_t fetchdat) +static int +opMOV_l_seg_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = ES; + else seteaw(ES); - break; - case 0x08: /*CS*/ + break; + case 0x08: /*CS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = CS; + else seteaw(CS); - break; - case 0x18: /*DS*/ + break; + case 0x18: /*DS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = DS; + else seteaw(DS); - break; - case 0x10: /*SS*/ + break; + case 0x10: /*SS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = SS; + else seteaw(SS); - break; - case 0x20: /*FS*/ + break; + case 0x20: /*FS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = FS; + else seteaw(FS); - break; - case 0x28: /*GS*/ + break; + case 0x28: /*GS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = GS; + else seteaw(GS); - break; - } + break; + } - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return cpu_state.abrt; } -static int opMOV_l_seg_a16(uint32_t fetchdat) +static int +opMOV_seg_w_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + uint16_t new_seg; - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES; - else seteaw(ES); - break; - case 0x08: /*CS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS; - else seteaw(CS); - break; - case 0x18: /*DS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS; - else seteaw(DS); - break; - case 0x10: /*SS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS; - else seteaw(SS); - break; - case 0x20: /*FS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS; - else seteaw(FS); - break; - case 0x28: /*GS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS; - else seteaw(GS); - break; - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + new_seg = geteaw(); + if (cpu_state.abrt) + return 1; - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; -} -static int opMOV_l_seg_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES; - else seteaw(ES); - break; - case 0x08: /*CS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS; - else seteaw(CS); - break; - case 0x18: /*DS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS; - else seteaw(DS); - break; - case 0x10: /*SS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS; - else seteaw(SS); - break; - case 0x20: /*FS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS; - else seteaw(FS); - break; - case 0x28: /*GS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS; - else seteaw(GS); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; -} - -static int opMOV_seg_w_a16(uint32_t fetchdat) -{ - uint16_t new_seg; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_seg=geteaw(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); - if (cpu_state.abrt) return 1; - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + loadseg(new_seg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + loadseg(new_seg, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + loadseg(new_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) return 1; - case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; -} -static int opMOV_seg_w_a32(uint32_t fetchdat) -{ - uint16_t new_seg; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_seg=geteaw(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); - if (cpu_state.abrt) return 1; - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) return 1; - case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); - break; - } + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return 1; + case 0x20: /*FS*/ + loadseg(new_seg, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + loadseg(new_seg, &cpu_state.seg_gs); + break; + } - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return cpu_state.abrt; } - - -static int opLDS_w_a16(uint32_t fetchdat) +static int +opMOV_seg_w_a32(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t new_seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); - return 0; -} -static int opLDS_w_a32(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); - return 0; -} -static int opLDS_l_a16(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); - return 0; -} -static int opLDS_l_a32(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); - return 0; -} - -static int opLSS_w_a16(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); + new_seg = geteaw(); + if (cpu_state.abrt) return 1; + + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + loadseg(new_seg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + loadseg(new_seg, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + loadseg(new_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return 1; + case 0x20: /*FS*/ + loadseg(new_seg, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + loadseg(new_seg, &cpu_state.seg_gs); + break; + } + + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return cpu_state.abrt; } -static int opLSS_w_a32(uint32_t fetchdat) + +static int +opLDS_w_a16(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr, seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); + return 0; } -static int opLSS_l_a16(uint32_t fetchdat) +static int +opLDS_w_a32(uint32_t fetchdat) { - uint32_t addr; - uint16_t seg; + uint16_t addr, seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); + return 0; } -static int opLSS_l_a32(uint32_t fetchdat) +static int +opLDS_l_a16(uint32_t fetchdat) { - uint32_t addr; - uint16_t seg; + uint32_t addr; + uint16_t seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0); + return 0; +} +static int +opLDS_l_a32(uint32_t fetchdat) +{ + uint32_t addr; + uint16_t seg; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1); + return 0; } -#define opLsel(name, sel) \ - static int opL ## name ## _w_a16(uint32_t fetchdat) \ - { \ - uint16_t addr, seg; \ - \ - fetch_ea_16(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - addr = readmemw(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opL ## name ## _w_a32(uint32_t fetchdat) \ - { \ - uint16_t addr, seg; \ - \ - fetch_ea_32(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - addr = readmemw(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); \ - return 0; \ - } \ - \ - static int opL ## name ## _l_a16(uint32_t fetchdat) \ - { \ - uint32_t addr; \ - uint16_t seg; \ - \ - fetch_ea_16(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ - addr = readmeml(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); \ - return 0; \ - } \ - \ - static int opL ## name ## _l_a32(uint32_t fetchdat) \ - { \ - uint32_t addr; \ - uint16_t seg; \ - \ - fetch_ea_32(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ - addr = readmeml(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); \ - return 0; \ - } +static int +opLSS_w_a16(uint32_t fetchdat) +{ + uint16_t addr, seg; + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); + return 1; +} +static int +opLSS_w_a32(uint32_t fetchdat) +{ + uint16_t addr, seg; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); + return 1; +} +static int +opLSS_l_a16(uint32_t fetchdat) +{ + uint32_t addr; + uint16_t seg; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); + return 1; +} +static int +opLSS_l_a32(uint32_t fetchdat) +{ + uint32_t addr; + uint16_t seg; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); + return 1; +} + +#define opLsel(name, sel) \ + static int opL##name##_w_a16(uint32_t fetchdat) \ + { \ + uint16_t addr, seg; \ + \ + fetch_ea_16(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + addr = readmemw(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 2); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opL##name##_w_a32(uint32_t fetchdat) \ + { \ + uint16_t addr, seg; \ + \ + fetch_ea_32(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + addr = readmemw(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 2); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); \ + return 0; \ + } \ + \ + static int opL##name##_l_a16(uint32_t fetchdat) \ + { \ + uint32_t addr; \ + uint16_t seg; \ + \ + fetch_ea_16(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ + addr = readmeml(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 4); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opL##name##_l_a32(uint32_t fetchdat) \ + { \ + uint32_t addr; \ + uint16_t seg; \ + \ + fetch_ea_32(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ + addr = readmeml(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 4); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1); \ + return 0; \ + } + +// clang-format off opLsel(ES, cpu_state.seg_es) opLsel(FS, cpu_state.seg_fs) opLsel(GS, cpu_state.seg_gs) +// clang-format on diff --git a/src/cpu/x86_ops_movx.h b/src/cpu/x86_ops_movx.h index 3ad89b7f0..1b607fb8b 100644 --- a/src/cpu/x86_ops_movx.h +++ b/src/cpu/x86_ops_movx.h @@ -1,209 +1,251 @@ -static int opMOVZX_w_b_a16(uint32_t fetchdat) +static int +opMOVZX_w_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_w_b_a32(uint32_t fetchdat) +static int +opMOVZX_w_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVZX_l_b_a16(uint32_t fetchdat) +static int +opMOVZX_l_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_l_b_a32(uint32_t fetchdat) +static int +opMOVZX_l_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVZX_w_w_a16(uint32_t fetchdat) +static int +opMOVZX_w_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_w_w_a32(uint32_t fetchdat) +static int +opMOVZX_w_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVZX_l_w_a16(uint32_t fetchdat) +static int +opMOVZX_l_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_l_w_a32(uint32_t fetchdat) +static int +opMOVZX_l_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVSX_w_b_a16(uint32_t fetchdat) +static int +opMOVSX_w_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].w |= 0xff00; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].w |= 0xff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVSX_w_b_a32(uint32_t fetchdat) +static int +opMOVSX_w_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].w |= 0xff00; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].w |= 0xff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVSX_l_b_a16(uint32_t fetchdat) +static int +opMOVSX_l_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].l |= 0xffffff00; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].l |= 0xffffff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVSX_l_b_a32(uint32_t fetchdat) +static int +opMOVSX_l_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].l |= 0xffffff00; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].l |= 0xffffff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVSX_l_w_a16(uint32_t fetchdat) +static int +opMOVSX_l_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x8000) - cpu_state.regs[cpu_reg].l |= 0xffff0000; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x8000) + cpu_state.regs[cpu_reg].l |= 0xffff0000; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVSX_l_w_a32(uint32_t fetchdat) +static int +opMOVSX_l_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x8000) - cpu_state.regs[cpu_reg].l |= 0xffff0000; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x8000) + cpu_state.regs[cpu_reg].l |= 0xffff0000; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_msr.h b/src/cpu/x86_ops_msr.h index 6624218e4..daae01d84 100644 --- a/src/cpu/x86_ops_msr.h +++ b/src/cpu/x86_ops_msr.h @@ -1,34 +1,33 @@ -static int opRDTSC(uint32_t fetchdat) +static int +opRDTSC(uint32_t fetchdat) { - if (!cpu_has_feature(CPU_FEATURE_RDTSC)) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - if ((cr4 & CR4_TSD) && CPL) - { - x86gpf("RDTSC when TSD set and CPL != 0", 0); - return 1; - } - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - CLOCK_CYCLES(1); + if (!cpu_has_feature(CPU_FEATURE_RDTSC)) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + if ((cr4 & CR4_TSD) && CPL) { + x86gpf("RDTSC when TSD set and CPL != 0", 0); + return 1; + } + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + CLOCK_CYCLES(1); #ifdef USE_DYNAREC - if (cpu_use_dynarec) - update_tsc(); + if (cpu_use_dynarec) + update_tsc(); #endif - return 0; + return 0; } -static int opRDPMC(uint32_t fetchdat) +static int +opRDPMC(uint32_t fetchdat) { - if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) - { - x86gpf("RDPMC not allowed", 0); - return 1; - } - EAX = EDX = 0; - CLOCK_CYCLES(1); - return 0; + if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) { + x86gpf("RDPMC not allowed", 0); + return 1; + } + EAX = EDX = 0; + CLOCK_CYCLES(1); + return 0; } diff --git a/src/cpu/x86_ops_mul.h b/src/cpu/x86_ops_mul.h index ca12a9add..552a9973a 100644 --- a/src/cpu/x86_ops_mul.h +++ b/src/cpu/x86_ops_mul.h @@ -1,263 +1,337 @@ -static int opIMUL_w_iw_a16(uint32_t fetchdat) +static int +opIMUL_w_iw_a16(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getword(); if (cpu_state.abrt) return 1; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getword(); + if (cpu_state.abrt) + return 1; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opIMUL_w_iw_a32(uint32_t fetchdat) +static int +opIMUL_w_iw_a32(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getword(); if (cpu_state.abrt) return 1; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getword(); + if (cpu_state.abrt) + return 1; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opIMUL_l_il_a16(uint32_t fetchdat) +static int +opIMUL_l_il_a16(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getlong(); if (cpu_state.abrt) return 1; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getlong(); + if (cpu_state.abrt) + return 1; - temp64 = ((int64_t)templ) * ((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(25); - PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(25); + PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opIMUL_l_il_a32(uint32_t fetchdat) +static int +opIMUL_l_il_a32(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getlong(); if (cpu_state.abrt) return 1; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getlong(); + if (cpu_state.abrt) + return 1; - temp64 = ((int64_t)templ) * ((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(25); - PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(25); + PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 1); + return 0; } -static int opIMUL_w_ib_a16(uint32_t fetchdat) +static int +opIMUL_w_ib_a16(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getbyte(); if (cpu_state.abrt) return 1; - if (tempw2 & 0x80) tempw2 |= 0xff00; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (tempw2 & 0x80) + tempw2 |= 0xff00; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opIMUL_w_ib_a32(uint32_t fetchdat) +static int +opIMUL_w_ib_a32(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getbyte(); if (cpu_state.abrt) return 1; - if (tempw2 & 0x80) tempw2 |= 0xff00; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (tempw2 & 0x80) + tempw2 |= 0xff00; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opIMUL_l_ib_a16(uint32_t fetchdat) +static int +opIMUL_l_ib_a16(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getbyte(); if (cpu_state.abrt) return 1; - if (templ2 & 0x80) templ2 |= 0xffffff00; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (templ2 & 0x80) + templ2 |= 0xffffff00; - temp64 = ((int64_t)templ)*((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opIMUL_l_ib_a32(uint32_t fetchdat) +static int +opIMUL_l_ib_a32(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getbyte(); if (cpu_state.abrt) return 1; - if (templ2 & 0x80) templ2 |= 0xffffff00; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (templ2 & 0x80) + templ2 |= 0xffffff00; - temp64 = ((int64_t)templ)*((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 1); + return 0; } - - -static int opIMUL_w_w_a16(uint32_t fetchdat) +static int +opIMUL_w_w_a16(uint32_t fetchdat) { - int32_t templ; + int32_t templ; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = templ & 0xFFFF; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + templ = (int32_t) (int16_t) cpu_state.regs[cpu_reg].w * (int32_t) (int16_t) geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = templ & 0xFFFF; + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES(18); + PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opIMUL_w_w_a32(uint32_t fetchdat) +static int +opIMUL_w_w_a32(uint32_t fetchdat) { - int32_t templ; + int32_t templ; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = templ & 0xFFFF; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + templ = (int32_t) (int16_t) cpu_state.regs[cpu_reg].w * (int32_t) (int16_t) geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = templ & 0xFFFF; + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES(18); + PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opIMUL_l_l_a16(uint32_t fetchdat) +static int +opIMUL_l_l_a16(uint32_t fetchdat) { - int64_t temp64; + int64_t temp64; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + temp64 = (int64_t) (int32_t) cpu_state.regs[cpu_reg].l * (int64_t) (int32_t) geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(30); + PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opIMUL_l_l_a32(uint32_t fetchdat) +static int +opIMUL_l_l_a32(uint32_t fetchdat) { - int64_t temp64; + int64_t temp64; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + temp64 = (int64_t) (int32_t) cpu_state.regs[cpu_reg].l * (int64_t) (int32_t) geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(30); + PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index 698cfc838..4fee881ea 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -1,460 +1,513 @@ -static int opARPL_a16(uint32_t fetchdat) +static int +opARPL_a16(uint32_t fetchdat) { - uint16_t temp_seg; + uint16_t temp_seg; - NOTRM - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp_seg = geteaw(); if (cpu_state.abrt) return 1; + NOTRM + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); + if (cpu_state.abrt) + return 1; - flags_rebuild(); - if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) - { - temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); - seteaw(temp_seg); if (cpu_state.abrt) return 1; - cpu_state.flags |= Z_FLAG; - } - else - cpu_state.flags &= ~Z_FLAG; + flags_rebuild(); + if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) { + temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); + seteaw(temp_seg); + if (cpu_state.abrt) + return 1; + cpu_state.flags |= Z_FLAG; + } else + cpu_state.flags &= ~Z_FLAG; - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 0); - return 0; + CLOCK_CYCLES(is486 ? 9 : 20); + PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 0); + return 0; } -static int opARPL_a32(uint32_t fetchdat) +static int +opARPL_a32(uint32_t fetchdat) { - uint16_t temp_seg; + uint16_t temp_seg; - NOTRM - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp_seg = geteaw(); if (cpu_state.abrt) return 1; + NOTRM + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); + if (cpu_state.abrt) + return 1; - flags_rebuild(); - if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) - { - temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); - seteaw(temp_seg); if (cpu_state.abrt) return 1; - cpu_state.flags |= Z_FLAG; - } - else - cpu_state.flags &= ~Z_FLAG; + flags_rebuild(); + if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) { + temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); + seteaw(temp_seg); + if (cpu_state.abrt) + return 1; + cpu_state.flags |= Z_FLAG; + } else + cpu_state.flags &= ~Z_FLAG; - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 1); - return 0; + CLOCK_CYCLES(is486 ? 9 : 20); + PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 1); + return 0; } -#define opLAR(name, fetch_ea, is32, ea32) \ - static int opLAR_ ## name(uint32_t fetchdat) \ - { \ - int valid; \ - uint16_t sel, desc = 0; \ - \ - NOTRM \ - fetch_ea(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - \ - flags_rebuild(); \ - if (!(sel & 0xfffc)) { cpu_state.flags &= ~Z_FLAG; return 0; } /*Null selector*/ \ - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ - if (valid) \ - { \ - cpl_override = 1; \ - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (cpu_state.abrt) return 1; \ - } \ - cpu_state.flags &= ~Z_FLAG; \ - if ((desc & 0x1f00) == 0x000) valid = 0; \ - if ((desc & 0x1f00) == 0x800) valid = 0; \ - if ((desc & 0x1f00) == 0xa00) valid = 0; \ - if ((desc & 0x1f00) == 0xd00) valid = 0; \ - if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \ - { \ - int dpl = (desc >> 13) & 3; \ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; \ - } \ - if (valid) \ - { \ - cpu_state.flags |= Z_FLAG; \ - cpl_override = 1; \ - if (is32) \ - cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \ - else \ - cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \ - cpl_override = 0; \ - } \ - CLOCK_CYCLES(11); \ - PREFETCH_RUN(11, 2, rmdat, 2,0,0,0, ea32); \ - return cpu_state.abrt; \ - } +#define opLAR(name, fetch_ea, is32, ea32) \ + static int opLAR_##name(uint32_t fetchdat) \ + { \ + int valid; \ + uint16_t sel, desc = 0; \ + \ + NOTRM \ + fetch_ea(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ + sel = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + \ + flags_rebuild(); \ + if (!(sel & 0xfffc)) { \ + cpu_state.flags &= ~Z_FLAG; \ + return 0; \ + } /*Null selector*/ \ + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ + if (valid) { \ + cpl_override = 1; \ + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ + cpl_override = 0; \ + if (cpu_state.abrt) \ + return 1; \ + } \ + cpu_state.flags &= ~Z_FLAG; \ + if ((desc & 0x1f00) == 0x000) \ + valid = 0; \ + if ((desc & 0x1f00) == 0x800) \ + valid = 0; \ + if ((desc & 0x1f00) == 0xa00) \ + valid = 0; \ + if ((desc & 0x1f00) == 0xd00) \ + valid = 0; \ + if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \ + { \ + int dpl = (desc >> 13) & 3; \ + if (dpl < CPL || dpl < (sel & 3)) \ + valid = 0; \ + } \ + if (valid) { \ + cpu_state.flags |= Z_FLAG; \ + cpl_override = 1; \ + if (is32) \ + cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \ + else \ + cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \ + cpl_override = 0; \ + } \ + CLOCK_CYCLES(11); \ + PREFETCH_RUN(11, 2, rmdat, 2, 0, 0, 0, ea32); \ + return cpu_state.abrt; \ + } opLAR(w_a16, fetch_ea_16, 0, 0) -opLAR(w_a32, fetch_ea_32, 0, 1) -opLAR(l_a16, fetch_ea_16, 1, 0) -opLAR(l_a32, fetch_ea_32, 1, 1) + opLAR(w_a32, fetch_ea_32, 0, 1) + opLAR(l_a16, fetch_ea_16, 1, 0) + opLAR(l_a32, fetch_ea_32, 1, 1) -#define opLSL(name, fetch_ea, is32, ea32) \ - static int opLSL_ ## name(uint32_t fetchdat) \ - { \ - int valid; \ - uint16_t sel, desc = 0; \ - \ - NOTRM \ - fetch_ea(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - cpu_state.flags &= ~Z_FLAG; \ - if (!(sel & 0xfffc)) return 0; /*Null selector*/ \ - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ - if (valid) \ - { \ - cpl_override = 1; \ - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (cpu_state.abrt) return 1; \ - } \ - if ((desc & 0x1400) == 0x400) valid = 0; /*Interrupt or trap or call gate*/ \ - if ((desc & 0x1f00) == 0x000) valid = 0; /*Invalid*/ \ - if ((desc & 0x1f00) == 0xa00) valid = 0; /*Invalid*/ \ - if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \ - { \ - int rpl = (desc >> 13) & 3; \ - if (rpl < CPL || rpl < (sel & 3)) valid = 0; \ - } \ - if (valid) \ - { \ - cpu_state.flags |= Z_FLAG; \ - cpl_override = 1; \ - if (is32) \ - { \ - cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ - cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \ - if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) \ - { \ - cpu_state.regs[cpu_reg].l <<= 12; \ - cpu_state.regs[cpu_reg].l |= 0xFFF; \ - } \ - } \ - else \ - cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ - cpl_override = 0; \ - } \ - CLOCK_CYCLES(10); \ - PREFETCH_RUN(10, 2, rmdat, 4,0,0,0, ea32); \ - return cpu_state.abrt; \ - } +#define opLSL(name, fetch_ea, is32, ea32) \ + static int opLSL_##name(uint32_t fetchdat) \ + { \ + int valid; \ + uint16_t sel, desc = 0; \ + \ + NOTRM \ + fetch_ea(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ + sel = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + cpu_state.flags &= ~Z_FLAG; \ + if (!(sel & 0xfffc)) \ + return 0; /*Null selector*/ \ + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ + if (valid) { \ + cpl_override = 1; \ + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ + cpl_override = 0; \ + if (cpu_state.abrt) \ + return 1; \ + } \ + if ((desc & 0x1400) == 0x400) \ + valid = 0; /*Interrupt or trap or call gate*/ \ + if ((desc & 0x1f00) == 0x000) \ + valid = 0; /*Invalid*/ \ + if ((desc & 0x1f00) == 0xa00) \ + valid = 0; /*Invalid*/ \ + if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \ + { \ + int rpl = (desc >> 13) & 3; \ + if (rpl < CPL || rpl < (sel & 3)) \ + valid = 0; \ + } \ + if (valid) { \ + cpu_state.flags |= Z_FLAG; \ + cpl_override = 1; \ + if (is32) { \ + cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ + cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \ + if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) { \ + cpu_state.regs[cpu_reg].l <<= 12; \ + cpu_state.regs[cpu_reg].l |= 0xFFF; \ + } \ + } else \ + cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ + cpl_override = 0; \ + } \ + CLOCK_CYCLES(10); \ + PREFETCH_RUN(10, 2, rmdat, 4, 0, 0, 0, ea32); \ + return cpu_state.abrt; \ + } -opLSL(w_a16, fetch_ea_16, 0, 0) -opLSL(w_a32, fetch_ea_32, 0, 1) -opLSL(l_a16, fetch_ea_16, 1, 0) -opLSL(l_a32, fetch_ea_32, 1, 1) + opLSL(w_a16, fetch_ea_16, 0, 0) + opLSL(w_a32, fetch_ea_32, 0, 1) + opLSL(l_a16, fetch_ea_16, 1, 0) + opLSL(l_a32, fetch_ea_32, 1, 1) - -static int op0F00_common(uint32_t fetchdat, int ea32) + static int op0F00_common(uint32_t fetchdat, int ea32) { - int dpl, valid, granularity; - uint32_t addr, base, limit; - uint16_t desc, sel; - uint8_t access, ar_high; + int dpl, valid, granularity; + uint32_t addr, base, limit; + uint16_t desc, sel; + uint8_t access, ar_high; - switch (rmdat & 0x38) - { - case 0x00: /*SLDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(ldt.seg); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); + switch (rmdat & 0x38) { + case 0x00: /*SLDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(ldt.seg); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x08: /*STR*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(tr.seg); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x10: /*LLDT*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + addr = (sel & ~7) + gdt.base; + limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); + base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); + access = readmemb(0, addr + 5); + ar_high = readmemb(0, addr + 6); + granularity = readmemb(0, addr + 6) & 0x80; + if (cpu_state.abrt) + return 1; + ldt.limit = limit; + ldt.access = access; + ldt.ar_high = ar_high; + if (granularity) { + ldt.limit <<= 12; + ldt.limit |= 0xfff; + } + ldt.base = base; + ldt.seg = sel; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32); + break; + case 0x18: /*LTR*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); break; - case 0x08: /*STR*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(tr.seg); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - case 0x10: /*LLDT*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - addr = (sel & ~7) + gdt.base; - limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); - base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); - access = readmemb(0, addr + 5); - ar_high = readmemb(0, addr + 6); - granularity = readmemb(0, addr + 6) & 0x80; - if (cpu_state.abrt) return 1; - ldt.limit = limit; - ldt.access = access; - ldt.ar_high = ar_high; - if (granularity) - { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base = base; - ldt.seg = sel; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); - break; - case 0x18: /*LTR*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - addr = (sel & ~7) + gdt.base; - limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); - base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); - access = readmemb(0, addr + 5); - ar_high = readmemb(0, addr + 6); - granularity = readmemb(0, addr + 6) & 0x80; - if (cpu_state.abrt) return 1; - access |= 2; - writememb(0, addr + 5, access); - if (cpu_state.abrt) return 1; - tr.seg = sel; - tr.limit = limit; - tr.access = access; - tr.ar_high = ar_high; - if (granularity) - { - tr.limit <<= 12; - tr.limit |= 0xFFF; - } - tr.base = base; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); - break; - case 0x20: /*VERR*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - cpu_state.flags &= ~Z_FLAG; - if (!(sel & 0xfffc)) return 0; /*Null selector*/ - cpl_override = 1; - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (cpu_state.abrt) return 1; - if (!(desc & 0x1000)) valid = 0; - if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/ - { - dpl = (desc >> 13) & 3; /*Check permissions*/ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; - } - if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/ - if (valid) cpu_state.flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); - break; - case 0x28: /*VERW*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - cpu_state.flags &= ~Z_FLAG; - if (!(sel & 0xfffc)) return 0; /*Null selector*/ - cpl_override = 1; - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (cpu_state.abrt) return 1; - if (!(desc & 0x1000)) valid = 0; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + addr = (sel & ~7) + gdt.base; + limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); + base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); + access = readmemb(0, addr + 5); + ar_high = readmemb(0, addr + 6); + granularity = readmemb(0, addr + 6) & 0x80; + if (cpu_state.abrt) + return 1; + access |= 2; + writememb(0, addr + 5, access); + if (cpu_state.abrt) + return 1; + tr.seg = sel; + tr.limit = limit; + tr.access = access; + tr.ar_high = ar_high; + if (granularity) { + tr.limit <<= 12; + tr.limit |= 0xFFF; + } + tr.base = base; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32); + break; + case 0x20: /*VERR*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + cpu_state.flags &= ~Z_FLAG; + if (!(sel & 0xfffc)) + return 0; /*Null selector*/ + cpl_override = 1; + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); + cpl_override = 0; + if (cpu_state.abrt) + return 1; + if (!(desc & 0x1000)) + valid = 0; + if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/ + { dpl = (desc >> 13) & 3; /*Check permissions*/ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; - if (desc & 0x0800) valid = 0; /*Code*/ - if (!(desc & 0x0200)) valid = 0; /*Read-only data*/ - if (valid) cpu_state.flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); - break; + if (dpl < CPL || dpl < (sel & 3)) + valid = 0; + } + if ((desc & 0x0800) && !(desc & 0x0200)) + valid = 0; /*Non-readable code*/ + if (valid) + cpu_state.flags |= Z_FLAG; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32); + break; + case 0x28: /*VERW*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + cpu_state.flags &= ~Z_FLAG; + if (!(sel & 0xfffc)) + return 0; /*Null selector*/ + cpl_override = 1; + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); + cpl_override = 0; + if (cpu_state.abrt) + return 1; + if (!(desc & 0x1000)) + valid = 0; + dpl = (desc >> 13) & 3; /*Check permissions*/ + if (dpl < CPL || dpl < (sel & 3)) + valid = 0; + if (desc & 0x0800) + valid = 0; /*Code*/ + if (!(desc & 0x0200)) + valid = 0; /*Read-only data*/ + if (valid) + cpu_state.flags |= Z_FLAG; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32); + break; - default: - cpu_state.pc -= 3; - x86illegal(); - break; - } - return cpu_state.abrt; + default: + cpu_state.pc -= 3; + x86illegal(); + break; + } + return cpu_state.abrt; } -static int op0F00_a16(uint32_t fetchdat) +static int +op0F00_a16(uint32_t fetchdat) { - NOTRM + NOTRM - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F00_common(fetchdat, 0); + return op0F00_common(fetchdat, 0); } -static int op0F00_a32(uint32_t fetchdat) +static int +op0F00_a32(uint32_t fetchdat) { - NOTRM + NOTRM - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F00_common(fetchdat, 1); + return op0F00_common(fetchdat, 1); } -static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) +static int +op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { - uint32_t base; - uint16_t limit, tempw; - switch (rmdat & 0x38) - { - case 0x00: /*SGDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(gdt.limit); - base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff); - if (is286) - base |= 0xff000000; - writememl(easeg, cpu_state.eaaddr + 2, base); - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); + uint32_t base; + uint16_t limit, tempw; + switch (rmdat & 0x38) { + case 0x00: /*SGDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(gdt.limit); + base = gdt.base; // is32 ? gdt.base : (gdt.base & 0xffffff); + if (is286) + base |= 0xff000000; + writememl(easeg, cpu_state.eaaddr + 2, base); + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32); + break; + case 0x08: /*SIDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(idt.limit); + base = idt.base; + if (is286) + base |= 0xff000000; + writememl(easeg, cpu_state.eaaddr + 2, base); + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32); + break; + case 0x10: /*LGDT*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); break; - case 0x08: /*SIDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(idt.limit); - base = idt.base; - if (is286) - base |= 0xff000000; - writememl(easeg, cpu_state.eaaddr + 2, base); - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + limit = geteaw(); + base = readmeml(0, easeg + cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + gdt.limit = limit; + gdt.base = base; + if (!is32) + gdt.base &= 0xffffff; + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32); + break; + case 0x18: /*LIDT*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); break; - case 0x10: /*LGDT*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + limit = geteaw(); + base = readmeml(0, easeg + cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + idt.limit = limit; + idt.base = base; + if (!is32) + idt.base &= 0xffffff; + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32); + break; + + case 0x20: /*SMSW*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (is486 || isibm486) + seteaw(msw); + else if (is386) + seteaw(msw | /* 0xFF00 */ 0xFFE0); + else + seteaw(msw | 0xFFF0); + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x30: /*LMSW*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (msw & 1)) { + x86gpf(NULL, 0); + break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + if (msw & 1) + tempw |= 1; + if (is386) { + tempw &= ~0x10; + tempw |= (msw & 0x10); + } else + tempw &= 0xF; + msw = tempw; + if (msw & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + + case 0x38: /*INVLPG*/ + if (is486 || isibm486) { + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); + break; } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - limit = geteaw(); - base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - gdt.limit = limit; - gdt.base = base; - if (!is32) gdt.base &= 0xffffff; - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32); - break; - case 0x18: /*LIDT*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - limit = geteaw(); - base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - idt.limit = limit; - idt.base = base; - if (!is32) idt.base &= 0xffffff; - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32); + SEG_CHECK_READ(cpu_state.ea_seg); + mmu_invalidate(ds + cpu_state.eaaddr); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, rmdat, 0, 0, 0, 0, ea32); break; + } - case 0x20: /*SMSW*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (is486 || isibm486) seteaw(msw); - else if (is386) seteaw(msw | /* 0xFF00 */ 0xFFE0); - else seteaw(msw | 0xFFF0); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - case 0x30: /*LMSW*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (msw&1)) - { - x86gpf(NULL, 0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - if (msw & 1) tempw |= 1; - if (is386) - { - tempw &= ~0x10; - tempw |= (msw & 0x10); - } - else tempw &= 0xF; - msw = tempw; - if (msw & 1) - cpu_cur_status |= CPU_STATUS_PMODE; - else - cpu_cur_status &= ~CPU_STATUS_PMODE; - PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - - case 0x38: /*INVLPG*/ - if (is486 || isibm486) - { - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL, 0); - break; - } - SEG_CHECK_READ(cpu_state.ea_seg); - mmu_invalidate(ds + cpu_state.eaaddr); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32); - break; - } - - default: - cpu_state.pc -= 3; - x86illegal(); - break; - } - return cpu_state.abrt; + default: + cpu_state.pc -= 3; + x86illegal(); + break; + } + return cpu_state.abrt; } -static int op0F01_w_a16(uint32_t fetchdat) +static int +op0F01_w_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 0, 0, 0); + return op0F01_common(fetchdat, 0, 0, 0); } -static int op0F01_w_a32(uint32_t fetchdat) +static int +op0F01_w_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F01_common(fetchdat, 0, 0, 1); + return op0F01_common(fetchdat, 0, 0, 1); } -static int op0F01_l_a16(uint32_t fetchdat) +static int +op0F01_l_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 1, 0, 0); + return op0F01_common(fetchdat, 1, 0, 0); } -static int op0F01_l_a32(uint32_t fetchdat) +static int +op0F01_l_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F01_common(fetchdat, 1, 0, 1); + return op0F01_common(fetchdat, 1, 0, 1); } -static int op0F01_286(uint32_t fetchdat) +static int +op0F01_286(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 0, 1, 0); + return op0F01_common(fetchdat, 0, 1, 0); } diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu/x86_ops_prefix.h index 3029da30a..eba59c17a 100644 --- a/src/cpu/x86_ops_prefix.h +++ b/src/cpu/x86_ops_prefix.h @@ -1,68 +1,73 @@ -#define op_seg(name, seg, opcode_table, normal_opcode_table) \ -static int op ## name ## _w_a16(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[fetchdat & 0xff]) \ - return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ - return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _l_a16(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x100]) \ - return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ +#define op_seg(name, seg, opcode_table, normal_opcode_table) \ + static int op##name##_w_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _w_a32(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x200]) \ - return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + } \ + \ + static int op##name##_w_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _l_a32(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x300]) \ - return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ -} + } +// clang-format off op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes) op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes) op_seg(ES, cpu_state.seg_es, x86_opcodes, x86_opcodes) @@ -83,79 +88,91 @@ op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes) op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes) op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) +// clang-format on -static int op_66(uint32_t fetchdat) /*Data size select*/ + static int op_66(uint32_t fetchdat) /*Data size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_67(uint32_t fetchdat) /*Address size select*/ +static int +op_67(uint32_t fetchdat) /*Address size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_66_REPE(uint32_t fetchdat) /*Data size select*/ +static int +op_66_REPE(uint32_t fetchdat) /*Data size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_67_REPE(uint32_t fetchdat) /*Address size select*/ +static int +op_67_REPE(uint32_t fetchdat) /*Address size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_66_REPNE(uint32_t fetchdat) /*Data size select*/ +static int +op_66_REPNE(uint32_t fetchdat) /*Data size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_67_REPNE(uint32_t fetchdat) /*Address size select*/ +static int +op_67_REPNE(uint32_t fetchdat) /*Address size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } diff --git a/src/cpu/x86_ops_rep.h b/src/cpu/x86_ops_rep.h index ffae30e09..67bd8433d 100644 --- a/src/cpu/x86_ops_rep.h +++ b/src/cpu/x86_ops_rep.h @@ -1,768 +1,883 @@ -#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ -static int opREP_INSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - addr64 = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - high_page = 0; \ - do_mmut_wb(es, DEST_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - temp = inb(DX); \ - writememb_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - addr64a[0] = addr64a[1] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - high_page = 0; \ - do_mmut_ww(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inw(DX); \ - writememw_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - high_page = 0; \ - do_mmut_wl(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inl(DX); \ - writememl_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_OUTSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - outb(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - outw(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - outl(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_MOVSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64 = addr64_2 = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64) ; \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_wb(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) break; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - writememb_n(es, DEST_REG, addr64_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_ww(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememw_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_wl(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememl_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ - \ -static int opREP_STOSB_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSW_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSL_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_LODSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - +#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ + static int opREP_INSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64 = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ + do_mmut_wb(es, DEST_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inb(DX); \ + writememb_n(es, DEST_REG, addr64, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_ww(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inw(DX); \ + writememw_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_wl(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inl(DX); \ + writememl_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_OUTSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + outb(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + outw(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + outl(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_MOVSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64 = addr64_2 = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint8_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_wb(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + writememb_n(es, DEST_REG, addr64_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint16_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_ww(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememw_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint32_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_wl(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememl_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_STOSB_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + writememb(es, DEST_REG, AL); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSW_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + writememw(es, DEST_REG, AX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSL_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + writememl(es, DEST_REG, EAX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_LODSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + AL = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + AX = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } #define CHEK_READ(a, b, c) - -#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ -static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - addr64 = addr64_2 = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint8_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = uncached = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_rb2(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub8(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint16_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = uncached = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_rw2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub16(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint32_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = uncached = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_rl2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub32(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_SCASB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub8(AL, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub16(AX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub32(EAX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} +#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ + static int opREP_CMPSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64 = addr64_2 = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint8_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = uncached = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_rb2(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemb_n(es, DEST_REG, addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub8(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint16_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = uncached = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_rw2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemw_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub16(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint32_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = uncached = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_rl2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmeml_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub32(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_SCASB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + uint8_t temp = readmemb(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub8(AL, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + uint16_t temp = readmemw(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub16(AX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + uint32_t temp = readmeml(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub32(EAX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } REP_OPS(a16, CX, SI, DI) REP_OPS(a32, ECX, ESI, EDI) REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0) -REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) +REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0) -REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) +REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) -static int opREPNE(uint32_t fetchdat) +static int +opREPNE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int opREPE(uint32_t fetchdat) +static int +opREPE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } diff --git a/src/cpu/x86_ops_rep_dyn.h b/src/cpu/x86_ops_rep_dyn.h index e63ed32fe..576baa403 100644 --- a/src/cpu/x86_ops_rep_dyn.h +++ b/src/cpu/x86_ops_rep_dyn.h @@ -1,703 +1,788 @@ -#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ -static int opREP_INSB_ ## size(uint32_t fetchdat) \ -{ \ - addr64 = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - high_page = 0; \ - do_mmut_wb(es, DEST_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - temp = inb(DX); \ - writememb_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= 15; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSW_ ## size(uint32_t fetchdat) \ -{ \ - addr64a[0] = addr64a[1] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - high_page = 0; \ - do_mmut_ww(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inw(DX); \ - writememw_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= 15; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSL_ ## size(uint32_t fetchdat) \ -{ \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - high_page = 0; \ - do_mmut_wl(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inl(DX); \ - writememl_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= 15; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_OUTSB_ ## size(uint32_t fetchdat) \ -{ \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - outb(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= 14; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSW_ ## size(uint32_t fetchdat) \ -{ \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - outw(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= 14; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSL_ ## size(uint32_t fetchdat) \ -{ \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - outl(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= 14; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_MOVSB_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64 = addr64_2 = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64) ; \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_wb(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) break; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - writememb_n(es, DEST_REG, addr64_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSW_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_ww(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememw_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSL_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_wl(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememl_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ - \ -static int opREP_STOSB_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSW_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSL_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_LODSB_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSW_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSL_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - +#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ + static int opREP_INSB_##size(uint32_t fetchdat) \ + { \ + addr64 = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ + do_mmut_wb(es, DEST_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inb(DX); \ + writememb_n(es, DEST_REG, addr64, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= 15; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSW_##size(uint32_t fetchdat) \ + { \ + addr64a[0] = addr64a[1] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_ww(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inw(DX); \ + writememw_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= 15; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSL_##size(uint32_t fetchdat) \ + { \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_wl(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inl(DX); \ + writememl_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= 15; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_OUTSB_##size(uint32_t fetchdat) \ + { \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + outb(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= 14; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSW_##size(uint32_t fetchdat) \ + { \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + outw(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= 14; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSL_##size(uint32_t fetchdat) \ + { \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + outl(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= 14; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_MOVSB_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64 = addr64_2 = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint8_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_wb(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + writememb_n(es, DEST_REG, addr64_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSW_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint16_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_ww(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememw_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSL_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint32_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_wl(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememl_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_STOSB_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + writememb(es, DEST_REG, AL); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSW_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + writememw(es, DEST_REG, AX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSL_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + writememl(es, DEST_REG, EAX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_LODSB_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + AL = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSW_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + AX = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSL_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } #define CHEK_READ(a, b, c) - -#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ -static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - \ - addr64 = addr64_2 = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint8_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = uncached = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_rb2(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - setsub8(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint16_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = uncached = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_rw2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - setsub16(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint32_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = uncached = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_rl2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - setsub32(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_SCASB_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - int cycles_end = cycles - 1000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub8(AL, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASW_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - int cycles_end = cycles - 1000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub16(AX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASL_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - int cycles_end = cycles - 1000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub32(EAX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} +#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ + static int opREP_CMPSB_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + \ + addr64 = addr64_2 = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint8_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = uncached = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_rb2(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemb_n(es, DEST_REG, addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + setsub8(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSW_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint16_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = uncached = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_rw2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemw_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + setsub16(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSL_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint32_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = uncached = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_rl2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmeml_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + setsub32(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_SCASB_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + int cycles_end = cycles - 1000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + uint8_t temp = readmemb(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub8(AL, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASW_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + int cycles_end = cycles - 1000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + uint16_t temp = readmemw(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub16(AX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASL_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + int cycles_end = cycles - 1000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + uint32_t temp = readmeml(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub32(EAX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } REP_OPS(a16, CX, SI, DI) REP_OPS(a32, ECX, ESI, EDI) REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0) -REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) +REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0) -REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) +REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) -static int opREPNE(uint32_t fetchdat) +static int +opREPNE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int opREPE(uint32_t fetchdat) +static int +opREPE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index 693fb0393..ec200f2d7 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -1,311 +1,291 @@ #ifdef USE_NEW_DYNAREC -#define CPU_SET_OXPC +# define CPU_SET_OXPC #else -#define CPU_SET_OXPC oxpc = cpu_state.pc; +# define CPU_SET_OXPC oxpc = cpu_state.pc; #endif -#define RETF_a16(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ - { \ - pmoderetf(0, stack_offset); \ - return 1; \ - } \ - CPU_SET_OXPC \ - if (stack32) \ - { \ - cpu_state.pc = readmemw(ss, ESP); \ - loadcs(readmemw(ss, ESP + 2)); \ - } \ - else \ - { \ - cpu_state.pc = readmemw(ss, SP); \ - loadcs(readmemw(ss, SP + 2)); \ - } \ - if (cpu_state.abrt) return 1; \ - if (stack32) ESP += 4 + stack_offset; \ - else SP += 4 + stack_offset; \ - cycles -= timing_retf_rm; +#define RETF_a16(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + pmoderetf(0, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmemw(ss, ESP); \ + loadcs(readmemw(ss, ESP + 2)); \ + } else { \ + cpu_state.pc = readmemw(ss, SP); \ + loadcs(readmemw(ss, SP + 2)); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 4 + stack_offset; \ + else \ + SP += 4 + stack_offset; \ + cycles -= timing_retf_rm; -#define RETF_a32(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ - { \ - pmoderetf(1, stack_offset); \ - return 1; \ - } \ - CPU_SET_OXPC \ - if (stack32) \ - { \ - cpu_state.pc = readmeml(ss, ESP); \ - loadcs(readmeml(ss, ESP + 4) & 0xffff); \ - } \ - else \ - { \ - cpu_state.pc = readmeml(ss, SP); \ - loadcs(readmeml(ss, SP + 4) & 0xffff); \ - } \ - if (cpu_state.abrt) return 1; \ - if (stack32) ESP += 8 + stack_offset; \ - else SP += 8 + stack_offset; \ - cycles -= timing_retf_rm; +#define RETF_a32(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + pmoderetf(1, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmeml(ss, ESP); \ + loadcs(readmeml(ss, ESP + 4) & 0xffff); \ + } else { \ + cpu_state.pc = readmeml(ss, SP); \ + loadcs(readmeml(ss, SP + 4) & 0xffff); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 8 + stack_offset; \ + else \ + SP += 8 + stack_offset; \ + cycles -= timing_retf_rm; -static int opRETF_a16(uint32_t fetchdat) +static int +opRETF_a16(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a16(0); + CPU_BLOCK_END(); + RETF_a16(0); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRETF_a32(uint32_t fetchdat) +static int +opRETF_a32(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a32(0); + CPU_BLOCK_END(); + RETF_a32(0); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; } -static int opRETF_a16_imm(uint32_t fetchdat) +static int +opRETF_a16_imm(uint32_t fetchdat) { - uint16_t offset = getwordf(); - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a16(offset); + CPU_BLOCK_END(); + RETF_a16(offset); - PREFETCH_RUN(cycles_old-cycles, 3, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRETF_a32_imm(uint32_t fetchdat) +static int +opRETF_a32_imm(uint32_t fetchdat) { - uint16_t offset = getwordf(); - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a32(offset); + CPU_BLOCK_END(); + RETF_a32(offset); - PREFETCH_RUN(cycles_old-cycles, 3, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; } -static int opIRET_186(uint32_t fetchdat) +static int +opIRET_186(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET_286(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + if (cr4 & CR4_VME) { + uint16_t new_pc, new_cs, new_flags; + + new_pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + new_flags = readmemw(ss, ((SP + 4) & 0xffff)); + if (cpu_state.abrt) return 1; - } - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; -} - -static int opIRET_286(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); + if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + x86gpf(NULL, 0); return 1; - } - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); + } + SP += 6; + if (new_flags & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; + loadcs(new_cs); + cpu_state.pc = new_pc; - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; + cycles -= timing_iret_rm; + } else { + x86gpf_expected(NULL, 0); + return 1; + } + } else { + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; + } + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; } -static int opIRET(uint32_t fetchdat) +static int +opIRETD(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - if (cr4 & CR4_VME) - { - uint16_t new_pc, new_cs, new_flags; - - new_pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - new_flags = readmemw(ss, ((SP + 4) & 0xffff)); - if (cpu_state.abrt) - return 1; - - if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) - { - x86gpf(NULL, 0); - return 1; - } - SP += 6; - if (new_flags & I_FLAG) - cpu_state.eflags |= VIF_FLAG; - else - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; - loadcs(new_cs); - cpu_state.pc = new_pc; - - cycles -= timing_iret_rm; - } - else - { - x86gpf_expected(NULL,0); - return 1; - } + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf_expected(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(1); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmeml(ss, ESP); + new_cs = readmemw(ss, ESP + 4); + cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, ESP + 10); + ESP += 12; + } else { + cpu_state.pc = readmeml(ss, SP); + new_cs = readmemw(ss, ((SP + 4) & 0xffff)); + cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); + SP += 12; } - else - { - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); + loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; -} - -static int opIRETD(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf_expected(NULL,0); - return 1; - } - if (msw & 1) - { - optype = IRET; - pmodeiret(1); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmeml(ss, ESP); - new_cs = readmemw(ss, ESP + 4); - cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; - cpu_state.eflags = readmemw(ss, ESP + 10); - ESP += 12; - } - else - { - cpu_state.pc = readmeml(ss, SP); - new_cs = readmemw(ss, ((SP + 4) & 0xffff)); - cpu_state.flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2; - cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); - SP += 12; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); - - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return cpu_state.abrt; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return cpu_state.abrt; } diff --git a/src/cpu/x86_ops_set.h b/src/cpu/x86_ops_set.h index f6fd50e69..30c076a6e 100644 --- a/src/cpu/x86_ops_set.h +++ b/src/cpu/x86_ops_set.h @@ -1,24 +1,25 @@ -#define opSET(condition) \ - static int opSET ## condition ## _a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ - } \ - \ - static int opSET ## condition ## _a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ - } +#define opSET(condition) \ + static int opSET##condition##_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + seteab((cond_##condition) ? 1 : 0); \ + CLOCK_CYCLES(4); \ + return cpu_state.abrt; \ + } \ + \ + static int opSET##condition##_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + seteab((cond_##condition) ? 1 : 0); \ + CLOCK_CYCLES(4); \ + return cpu_state.abrt; \ + } +// clang-format off opSET(O) opSET(NO) opSET(B) @@ -35,3 +36,4 @@ opSET(L) opSET(NL) opSET(LE) opSET(NLE) +// clang-format on diff --git a/src/cpu/x86_ops_shift.h b/src/cpu/x86_ops_shift.h index 5d03cb9a9..9c11a32f0 100644 --- a/src/cpu/x86_ops_shift.h +++ b/src/cpu/x86_ops_shift.h @@ -1,852 +1,1056 @@ #ifdef USE_NEW_DYNAREC -#define OP_SHIFT_b(c, ea32) \ - { \ - uint8_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL b, c*/ \ - temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL8, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR b,CL*/ \ - temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR8, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR b,CL*/ \ - temp = (int8_t)temp >> c; \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_b(c, ea32) \ + { \ + uint8_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL b, c*/ \ + temp = (temp << (c & 7)) | (temp >> (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR b,CL*/ \ + temp = (temp >> (c & 7)) | (temp << (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL b,CL*/ \ + seteab(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR b,CL*/ \ + seteab(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR b,CL*/ \ + temp = (int8_t) temp >> c; \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_w(c, ea32) \ - { \ - uint16_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL w, c*/ \ - temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL16, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR w,CL*/ \ - temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR16, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x8000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x8000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR w, c*/ \ - temp = (int16_t)temp >> c; \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_w(c, ea32) \ + { \ + uint16_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL w, c*/ \ + temp = (temp << (c & 15)) | (temp >> (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR w,CL*/ \ + temp = (temp >> (c & 15)) | (temp << (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x8000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x8000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL w, c*/ \ + seteaw(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR w, c*/ \ + seteaw(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR w, c*/ \ + temp = (int16_t) temp >> c; \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_l(c, ea32) \ - { \ - uint32_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL l, c*/ \ - temp = (temp << c) | (temp >> (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL32, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR l,CL*/ \ - temp = (temp >> c) | (temp << (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR32, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL l, c*/ \ - temp2 = CF_SET(); \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80000000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x18: /*RCR l, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80000000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x38: /*SAR l, c*/ \ - temp = (int32_t)temp >> c; \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - } \ +# define OP_SHIFT_l(c, ea32) \ + { \ + uint32_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL l, c*/ \ + temp = (temp << c) | (temp >> (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR l,CL*/ \ + temp = (temp >> c) | (temp << (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL l, c*/ \ + temp2 = CF_SET(); \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80000000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x18: /*RCR l, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80000000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL l, c*/ \ + seteal(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x28: /*SHR l, c*/ \ + seteal(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x38: /*SAR l, c*/ \ + temp = (int32_t) temp >> c; \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + } \ } #else -#define OP_SHIFT_b(c, ea32) \ - { \ - uint8_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL b, c*/ \ - temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR b,CL*/ \ - temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x80) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR b,CL*/ \ - temp = (int8_t)temp >> c; \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_b(c, ea32) \ + { \ + uint8_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL b, c*/ \ + temp = (temp << (c & 7)) | (temp >> (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 7)) & 1) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR b,CL*/ \ + temp = (temp >> (c & 7)) | (temp << (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL b,CL*/ \ + seteab(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR b,CL*/ \ + seteab(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR b,CL*/ \ + temp = (int8_t) temp >> c; \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_w(c, ea32) \ - { \ - uint16_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL w, c*/ \ - temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR w,CL*/ \ - temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x8000) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x8000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x8000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR w, c*/ \ - temp = (int16_t)temp >> c; \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_w(c, ea32) \ + { \ + uint16_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL w, c*/ \ + temp = (temp << (c & 15)) | (temp >> (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 15)) & 1) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR w,CL*/ \ + temp = (temp >> (c & 15)) | (temp << (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x8000) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x8000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x8000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL w, c*/ \ + seteaw(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR w, c*/ \ + seteaw(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR w, c*/ \ + temp = (int16_t) temp >> c; \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_l(c, ea32) \ - { \ - uint32_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL l, c*/ \ - temp = (temp << c) | (temp >> (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR l,CL*/ \ - temp = (temp >> c) | (temp << (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL l, c*/ \ - temp2 = CF_SET(); \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80000000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x18: /*RCR l, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80000000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x38: /*SAR l, c*/ \ - temp = (int32_t)temp >> c; \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - } \ +# define OP_SHIFT_l(c, ea32) \ + { \ + uint32_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL l, c*/ \ + temp = (temp << c) | (temp >> (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 31)) & 1) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR l,CL*/ \ + temp = (temp >> c) | (temp << (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80000000) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL l, c*/ \ + temp2 = CF_SET(); \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80000000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x18: /*RCR l, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80000000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL l, c*/ \ + seteal(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x28: /*SHR l, c*/ \ + seteal(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x38: /*SAR l, c*/ \ + temp = (int32_t) temp >> c; \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + } \ } #endif -static int opC0_a16(uint32_t fetchdat) +static int +opC0_a16(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 0); + return 0; } -static int opC0_a32(uint32_t fetchdat) +static int +opC0_a32(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 1); + return 0; } -static int opC1_w_a16(uint32_t fetchdat) +static int +opC1_w_a16(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 0); + return 0; } -static int opC1_w_a32(uint32_t fetchdat) +static int +opC1_w_a32(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 1); + return 0; } -static int opC1_l_a16(uint32_t fetchdat) +static int +opC1_l_a16(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 0); + return 0; } -static int opC1_l_a32(uint32_t fetchdat) +static int +opC1_l_a32(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } -static int opD0_a16(uint32_t fetchdat) +static int +opD0_a16(uint32_t fetchdat) { - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; + int c = 1; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 0); + return 0; } -static int opD0_a32(uint32_t fetchdat) +static int +opD0_a32(uint32_t fetchdat) { - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; + int c = 1; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 1); + return 0; } -static int opD1_w_a16(uint32_t fetchdat) +static int +opD1_w_a16(uint32_t fetchdat) { - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; + int c = 1; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 0); + return 0; } -static int opD1_w_a32(uint32_t fetchdat) +static int +opD1_w_a32(uint32_t fetchdat) { - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; + int c = 1; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 1); + return 0; } -static int opD1_l_a16(uint32_t fetchdat) +static int +opD1_l_a16(uint32_t fetchdat) { - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; + int c = 1; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 0); + return 0; } -static int opD1_l_a32(uint32_t fetchdat) +static int +opD1_l_a32(uint32_t fetchdat) { - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; + int c = 1; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } -static int opD2_a16(uint32_t fetchdat) +static int +opD2_a16(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 0); + return 0; } -static int opD2_a32(uint32_t fetchdat) +static int +opD2_a32(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 1); + return 0; } -static int opD3_w_a16(uint32_t fetchdat) +static int +opD3_w_a16(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 0); + return 0; } -static int opD3_w_a32(uint32_t fetchdat) +static int +opD3_w_a32(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 1); + return 0; } -static int opD3_l_a16(uint32_t fetchdat) +static int +opD3_l_a16(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 0); + return 0; } -static int opD3_l_a32(uint32_t fetchdat) +static int +opD3_l_a32(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } - -#define SHLD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ - templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ - if (count <= 16) tempw = templ >> (16 - count); \ - else tempw = (templ << count) >> 16; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } +#define SHLD_w() \ + if (count) { \ + int tempc; \ + uint32_t templ; \ + uint16_t tempw = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ + templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ + if (count <= 16) \ + tempw = templ >> (16 - count); \ + else \ + tempw = (templ << count) >> 16; \ + seteaw(tempw); \ + if (cpu_state.abrt) \ + return 1; \ + setznp16(tempw); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } #define SHLD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ - templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } + if (count) { \ + int tempc; \ + uint32_t templ = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ + templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \ + seteal(templ); \ + if (cpu_state.abrt) \ + return 1; \ + setznp32(templ); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } - -#define SHRD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (tempw >> (count - 1)) & 1; \ - templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ - tempw = templ >> count; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } +#define SHRD_w() \ + if (count) { \ + int tempc; \ + uint32_t templ; \ + uint16_t tempw = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (tempw >> (count - 1)) & 1; \ + templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ + tempw = templ >> count; \ + seteaw(tempw); \ + if (cpu_state.abrt) \ + return 1; \ + setznp16(tempw); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } #define SHRD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (templ >> (count - 1)) & 1; \ - templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } + if (count) { \ + int tempc; \ + uint32_t templ = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (templ >> (count - 1)) & 1; \ + templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \ + seteal(templ); \ + if (cpu_state.abrt) \ + return 1; \ + setznp32(templ); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } -#define opSHxD(operation) \ - static int op ## operation ## _i_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = getbyte() & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _CL_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = CL & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _i_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = getbyte() & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } \ - static int op ## operation ## _CL_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = CL & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } +#define opSHxD(operation) \ + static int op##operation##_i_a16(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = getbyte() & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); \ + return 0; \ + } \ + static int op##operation##_CL_a16(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = CL & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); \ + return 0; \ + } \ + static int op##operation##_i_a32(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = getbyte() & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); \ + return 0; \ + } \ + static int op##operation##_CL_a32(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = CL & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); \ + return 0; \ + } +// clang-format off opSHxD(SHLD_w) opSHxD(SHLD_l) opSHxD(SHRD_w) opSHxD(SHRD_l) +// clang-format on diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 58f24c6f9..8217a9e5a 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -1,38 +1,38 @@ -#define PUSH_W_OP(reg) \ - static int opPUSH_ ## reg (uint32_t fetchdat) \ - { \ - PUSH_W(reg); \ - CLOCK_CYCLES((is486) ? 1 : 2); \ - PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } +#define PUSH_W_OP(reg) \ + static int opPUSH_##reg(uint32_t fetchdat) \ + { \ + PUSH_W(reg); \ + CLOCK_CYCLES((is486) ? 1 : 2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } -#define PUSH_L_OP(reg) \ - static int opPUSH_ ## reg (uint32_t fetchdat) \ - { \ - PUSH_L(reg); \ - CLOCK_CYCLES((is486) ? 1 : 2); \ - PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \ - return cpu_state.abrt; \ - } +#define PUSH_L_OP(reg) \ + static int opPUSH_##reg(uint32_t fetchdat) \ + { \ + PUSH_L(reg); \ + CLOCK_CYCLES((is486) ? 1 : 2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 1, 0); \ + return cpu_state.abrt; \ + } -#define POP_W_OP(reg) \ - static int opPOP_ ## reg (uint32_t fetchdat) \ - { \ - reg = POP_W(); \ - CLOCK_CYCLES((is486) ? 1 : 4); \ - PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); \ - return cpu_state.abrt; \ - } +#define POP_W_OP(reg) \ + static int opPOP_##reg(uint32_t fetchdat) \ + { \ + reg = POP_W(); \ + CLOCK_CYCLES((is486) ? 1 : 4); \ + PREFETCH_RUN(4, 1, -1, 1, 0, 0, 0, 0); \ + return cpu_state.abrt; \ + } -#define POP_L_OP(reg) \ - static int opPOP_ ## reg (uint32_t fetchdat) \ - { \ - reg = POP_L(); \ - CLOCK_CYCLES((is486) ? 1 : 4); \ - PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); \ - return cpu_state.abrt; \ - } +#define POP_L_OP(reg) \ + static int opPOP_##reg(uint32_t fetchdat) \ + { \ + reg = POP_L(); \ + CLOCK_CYCLES((is486) ? 1 : 4); \ + PREFETCH_RUN(4, 1, -1, 0, 1, 0, 0, 0); \ + return cpu_state.abrt; \ + } PUSH_W_OP(AX) PUSH_W_OP(BX) @@ -70,421 +70,531 @@ POP_L_OP(EDI) POP_L_OP(EBP) POP_L_OP(ESP) - -static int opPUSHA_w(uint32_t fetchdat) +static int +opPUSHA_w(uint32_t fetchdat) { - if (stack32) - { - writememw(ss, ESP - 2, AX); - writememw(ss, ESP - 4, CX); - writememw(ss, ESP - 6, DX); - writememw(ss, ESP - 8, BX); - writememw(ss, ESP - 10, SP); - writememw(ss, ESP - 12, BP); - writememw(ss, ESP - 14, SI); - writememw(ss, ESP - 16, DI); - if (!cpu_state.abrt) ESP -= 16; - } - else - { - writememw(ss, ((SP - 2) & 0xFFFF), AX); - writememw(ss, ((SP - 4) & 0xFFFF), CX); - writememw(ss, ((SP - 6) & 0xFFFF), DX); - writememw(ss, ((SP - 8) & 0xFFFF), BX); - writememw(ss, ((SP - 10) & 0xFFFF), SP); - writememw(ss, ((SP - 12) & 0xFFFF), BP); - writememw(ss, ((SP - 14) & 0xFFFF), SI); - writememw(ss, ((SP - 16) & 0xFFFF), DI); - if (!cpu_state.abrt) SP -= 16; - } - CLOCK_CYCLES((is486) ? 11 : 18); - PREFETCH_RUN(18, 1, -1, 0,0,8,0, 0); - return cpu_state.abrt; + if (stack32) { + writememw(ss, ESP - 2, AX); + writememw(ss, ESP - 4, CX); + writememw(ss, ESP - 6, DX); + writememw(ss, ESP - 8, BX); + writememw(ss, ESP - 10, SP); + writememw(ss, ESP - 12, BP); + writememw(ss, ESP - 14, SI); + writememw(ss, ESP - 16, DI); + if (!cpu_state.abrt) + ESP -= 16; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), AX); + writememw(ss, ((SP - 4) & 0xFFFF), CX); + writememw(ss, ((SP - 6) & 0xFFFF), DX); + writememw(ss, ((SP - 8) & 0xFFFF), BX); + writememw(ss, ((SP - 10) & 0xFFFF), SP); + writememw(ss, ((SP - 12) & 0xFFFF), BP); + writememw(ss, ((SP - 14) & 0xFFFF), SI); + writememw(ss, ((SP - 16) & 0xFFFF), DI); + if (!cpu_state.abrt) + SP -= 16; + } + CLOCK_CYCLES((is486) ? 11 : 18); + PREFETCH_RUN(18, 1, -1, 0, 0, 8, 0, 0); + return cpu_state.abrt; } -static int opPUSHA_l(uint32_t fetchdat) +static int +opPUSHA_l(uint32_t fetchdat) { - if (stack32) - { - writememl(ss, ESP - 4, EAX); - writememl(ss, ESP - 8, ECX); - writememl(ss, ESP - 12, EDX); - writememl(ss, ESP - 16, EBX); - writememl(ss, ESP - 20, ESP); - writememl(ss, ESP - 24, EBP); - writememl(ss, ESP - 28, ESI); - writememl(ss, ESP - 32, EDI); - if (!cpu_state.abrt) ESP -= 32; - } - else - { - writememl(ss, ((SP - 4) & 0xFFFF), EAX); - writememl(ss, ((SP - 8) & 0xFFFF), ECX); - writememl(ss, ((SP - 12) & 0xFFFF), EDX); - writememl(ss, ((SP - 16) & 0xFFFF), EBX); - writememl(ss, ((SP - 20) & 0xFFFF), ESP); - writememl(ss, ((SP - 24) & 0xFFFF), EBP); - writememl(ss, ((SP - 28) & 0xFFFF), ESI); - writememl(ss, ((SP - 32) & 0xFFFF), EDI); - if (!cpu_state.abrt) SP -= 32; - } - CLOCK_CYCLES((is486) ? 11 : 18); - PREFETCH_RUN(18, 1, -1, 0,0,0,8, 0); - return cpu_state.abrt; + if (stack32) { + writememl(ss, ESP - 4, EAX); + writememl(ss, ESP - 8, ECX); + writememl(ss, ESP - 12, EDX); + writememl(ss, ESP - 16, EBX); + writememl(ss, ESP - 20, ESP); + writememl(ss, ESP - 24, EBP); + writememl(ss, ESP - 28, ESI); + writememl(ss, ESP - 32, EDI); + if (!cpu_state.abrt) + ESP -= 32; + } else { + writememl(ss, ((SP - 4) & 0xFFFF), EAX); + writememl(ss, ((SP - 8) & 0xFFFF), ECX); + writememl(ss, ((SP - 12) & 0xFFFF), EDX); + writememl(ss, ((SP - 16) & 0xFFFF), EBX); + writememl(ss, ((SP - 20) & 0xFFFF), ESP); + writememl(ss, ((SP - 24) & 0xFFFF), EBP); + writememl(ss, ((SP - 28) & 0xFFFF), ESI); + writememl(ss, ((SP - 32) & 0xFFFF), EDI); + if (!cpu_state.abrt) + SP -= 32; + } + CLOCK_CYCLES((is486) ? 11 : 18); + PREFETCH_RUN(18, 1, -1, 0, 0, 0, 8, 0); + return cpu_state.abrt; } -static int opPOPA_w(uint32_t fetchdat) +static int +opPOPA_w(uint32_t fetchdat) { - if (stack32) - { - DI = readmemw(ss, ESP); if (cpu_state.abrt) return 1; - SI = readmemw(ss, ESP + 2); if (cpu_state.abrt) return 1; - BP = readmemw(ss, ESP + 4); if (cpu_state.abrt) return 1; - BX = readmemw(ss, ESP + 8); if (cpu_state.abrt) return 1; - DX = readmemw(ss, ESP + 10); if (cpu_state.abrt) return 1; - CX = readmemw(ss, ESP + 12); if (cpu_state.abrt) return 1; - AX = readmemw(ss, ESP + 14); if (cpu_state.abrt) return 1; - ESP += 16; - } - else - { - DI = readmemw(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; - SI = readmemw(ss, ((SP + 2) & 0xFFFF)); if (cpu_state.abrt) return 1; - BP = readmemw(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; - BX = readmemw(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; - DX = readmemw(ss, ((SP + 10) & 0xFFFF)); if (cpu_state.abrt) return 1; - CX = readmemw(ss, ((SP + 12) & 0xFFFF)); if (cpu_state.abrt) return 1; - AX = readmemw(ss, ((SP + 14) & 0xFFFF)); if (cpu_state.abrt) return 1; - SP += 16; - } - CLOCK_CYCLES((is486) ? 9 : 24); - PREFETCH_RUN(24, 1, -1, 7,0,0,0, 0); - return 0; -} -static int opPOPA_l(uint32_t fetchdat) -{ - if (stack32) - { - EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ESP + 16); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ESP + 20); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1; - ESP += 32; - } - else - { - EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (cpu_state.abrt) return 1; - SP += 32; - } - CLOCK_CYCLES((is486) ? 9 : 24); - PREFETCH_RUN(24, 1, -1, 0,7,0,0, 0); - return 0; -} - -static int opPUSH_imm_w(uint32_t fetchdat) -{ - uint16_t val = getwordf(); - PUSH_W(val); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opPUSH_imm_l(uint32_t fetchdat) -{ - uint32_t val = getlong(); if (cpu_state.abrt) return 1; - PUSH_L(val); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} - -static int opPUSH_imm_bw(uint32_t fetchdat) -{ - uint16_t tempw = getbytef(); - - if (tempw & 0x80) tempw |= 0xFF00; - PUSH_W(tempw); - - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opPUSH_imm_bl(uint32_t fetchdat) -{ - uint32_t templ = getbytef(); - - if (templ & 0x80) templ |= 0xFFFFFF00; - PUSH_L(templ); - - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} - -static int opPOPW_a16(uint32_t fetchdat) -{ - uint16_t temp; - - temp = POP_W(); if (cpu_state.abrt) return 1; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(temp); + if (stack32) { + DI = readmemw(ss, ESP); if (cpu_state.abrt) - { - if (stack32) ESP -= 2; - else SP -= 2; - } - - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 0); - return cpu_state.abrt; -} -static int opPOPW_a32(uint32_t fetchdat) -{ - uint16_t temp; - - temp = POP_W(); if (cpu_state.abrt) return 1; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(temp); + return 1; + SI = readmemw(ss, ESP + 2); if (cpu_state.abrt) - { - if (stack32) ESP -= 2; - else SP -= 2; - } - - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 1); - return cpu_state.abrt; -} - -static int opPOPL_a16(uint32_t fetchdat) -{ - uint32_t temp; - - temp = POP_L(); if (cpu_state.abrt) return 1; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(temp); + return 1; + BP = readmemw(ss, ESP + 4); if (cpu_state.abrt) - { - if (stack32) ESP -= 4; - else SP -= 4; - } - - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 0); - return cpu_state.abrt; -} -static int opPOPL_a32(uint32_t fetchdat) -{ - uint32_t temp; - - temp = POP_L(); if (cpu_state.abrt) return 1; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(temp); + return 1; + BX = readmemw(ss, ESP + 8); if (cpu_state.abrt) - { - if (stack32) ESP -= 4; - else SP -= 4; - } - - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 1); - return cpu_state.abrt; + return 1; + DX = readmemw(ss, ESP + 10); + if (cpu_state.abrt) + return 1; + CX = readmemw(ss, ESP + 12); + if (cpu_state.abrt) + return 1; + AX = readmemw(ss, ESP + 14); + if (cpu_state.abrt) + return 1; + ESP += 16; + } else { + DI = readmemw(ss, ((SP) &0xFFFF)); + if (cpu_state.abrt) + return 1; + SI = readmemw(ss, ((SP + 2) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + BP = readmemw(ss, ((SP + 4) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + BX = readmemw(ss, ((SP + 8) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + DX = readmemw(ss, ((SP + 10) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + CX = readmemw(ss, ((SP + 12) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + AX = readmemw(ss, ((SP + 14) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + SP += 16; + } + CLOCK_CYCLES((is486) ? 9 : 24); + PREFETCH_RUN(24, 1, -1, 7, 0, 0, 0, 0); + return 0; } - - -static int opENTER_w(uint32_t fetchdat) +static int +opPOPA_l(uint32_t fetchdat) { - uint16_t offset; - int count; - uint32_t tempEBP, tempESP, frame_ptr; -#ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; -#endif - uint16_t tempw; - - offset = getwordf(); - count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - tempEBP = EBP; - tempESP = ESP; - - PUSH_W(BP); if (cpu_state.abrt) return 1; - frame_ptr = ESP; - - if (count > 0) - { - while (--count) - { - BP -= 2; - tempw = readmemw(ss, BP); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - PUSH_W(tempw); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 4); -#ifndef IS_DYNAREC - reads++; writes++; instr_cycles += (is486) ? 3 : 4; -#endif - } - PUSH_W(frame_ptr); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 5); -#ifndef IS_DYNAREC - writes++; instr_cycles += (is486) ? 3 : 5; -#endif - } - BP = frame_ptr; - - if (stack32) ESP -= offset; - else SP -= offset; - CLOCK_CYCLES((is486) ? 14 : 10); -#ifndef IS_DYNAREC - instr_cycles += (is486) ? 14 : 10; - PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0); -#endif - return 0; + if (stack32) { + EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1; + ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1; + EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1; + EBX = readmeml(ss, ESP + 16); if (cpu_state.abrt) return 1; + EDX = readmeml(ss, ESP + 20); if (cpu_state.abrt) return 1; + ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1; + EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1; + ESP += 32; + } else { + EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; + ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; + EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; + EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (cpu_state.abrt) return 1; + EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (cpu_state.abrt) return 1; + ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (cpu_state.abrt) return 1; + EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (cpu_state.abrt) return 1; + SP += 32; + } + CLOCK_CYCLES((is486) ? 9 : 24); + PREFETCH_RUN(24, 1, -1, 0, 7, 0, 0, 0); + return 0; } -static int opENTER_l(uint32_t fetchdat) + +static int +opPUSH_imm_w(uint32_t fetchdat) { - uint16_t offset; - int count; - uint32_t tempEBP, tempESP, frame_ptr; -#ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; -#endif - uint32_t templ; - - offset = getwordf(); - count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - tempEBP = EBP; tempESP = ESP; - - PUSH_L(EBP); if (cpu_state.abrt) return 1; - frame_ptr = ESP; - - if (count > 0) - { - while (--count) - { - EBP -= 4; - templ = readmeml(ss, EBP); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - PUSH_L(templ); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 4); -#ifndef IS_DYNAREC - reads++; writes++; instr_cycles += (is486) ? 3 : 4; -#endif - } - PUSH_L(frame_ptr); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 5); -#ifndef IS_DYNAREC - writes++; instr_cycles += (is486) ? 3 : 5; -#endif - } - EBP = frame_ptr; - - if (stack32) ESP -= offset; - else SP -= offset; - CLOCK_CYCLES((is486) ? 14 : 10); -#ifndef IS_DYNAREC - instr_cycles += (is486) ? 14 : 10; - PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0); -#endif - return 0; + uint16_t val = getwordf(); + PUSH_W(val); + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; } - - -static int opLEAVE_w(uint32_t fetchdat) +static int +opPUSH_imm_l(uint32_t fetchdat) { - uint32_t tempESP = ESP; - uint16_t temp; - - SP = BP; - temp = POP_W(); - if (cpu_state.abrt) { ESP = tempESP; return 1; } - BP = temp; - - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); - return 0; + uint32_t val = getlong(); + if (cpu_state.abrt) + return 1; + PUSH_L(val); + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 3, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; } -static int opLEAVE_l(uint32_t fetchdat) + +static int +opPUSH_imm_bw(uint32_t fetchdat) { - uint32_t tempESP = ESP; - uint32_t temp; + uint16_t tempw = getbytef(); - ESP = EBP; - temp = POP_L(); - if (cpu_state.abrt) { ESP = tempESP; return 1; } - EBP = temp; + if (tempw & 0x80) + tempw |= 0xFF00; + PUSH_W(tempw); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 2, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opPUSH_imm_bl(uint32_t fetchdat) +{ + uint32_t templ = getbytef(); + + if (templ & 0x80) + templ |= 0xFFFFFF00; + PUSH_L(templ); + + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 2, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; } +static int +opPOPW_a16(uint32_t fetchdat) +{ + uint16_t temp; -#define PUSH_SEG_OPS(seg) \ - static int opPUSH_ ## seg ## _w(uint32_t fetchdat) \ - { \ - PUSH_W(seg); \ - CLOCK_CYCLES(2); \ - PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } \ - static int opPUSH_ ## seg ## _l(uint32_t fetchdat) \ - { \ - PUSH_L(seg); \ - CLOCK_CYCLES(2); \ - PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \ - return cpu_state.abrt; \ + temp = POP_W(); + if (cpu_state.abrt) + return 1; + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 2; + else + SP -= 2; + } + + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return cpu_state.abrt; +} +static int +opPOPW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + temp = POP_W(); + if (cpu_state.abrt) + return 1; + + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 2; + else + SP -= 2; + } + + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return cpu_state.abrt; +} + +static int +opPOPL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + temp = POP_L(); + if (cpu_state.abrt) + return 1; + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 4; + else + SP -= 4; + } + + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0, 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + return cpu_state.abrt; +} +static int +opPOPL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + temp = POP_L(); + if (cpu_state.abrt) + return 1; + + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 4; + else + SP -= 4; + } + + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0, 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + return cpu_state.abrt; +} + +static int +opENTER_w(uint32_t fetchdat) +{ + uint16_t offset; + int count; + uint32_t tempEBP, tempESP, frame_ptr; +#ifndef IS_DYNAREC + int reads = 0, writes = 1, instr_cycles = 0; +#endif + uint16_t tempw; + + offset = getwordf(); + count = (fetchdat >> 16) & 0xff; + cpu_state.pc++; + tempEBP = EBP; + tempESP = ESP; + + PUSH_W(BP); + if (cpu_state.abrt) + return 1; + frame_ptr = ESP; + + if (count > 0) { + while (--count) { + BP -= 2; + tempw = readmemw(ss, BP); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + PUSH_W(tempw); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 4); +#ifndef IS_DYNAREC + reads++; + writes++; + instr_cycles += (is486) ? 3 : 4; +#endif } - -#define POP_SEG_OPS(seg, realseg) \ - static int opPOP_ ## seg ## _w(uint32_t fetchdat) \ - { \ - uint16_t temp_seg; \ - uint32_t temp_esp = ESP; \ - temp_seg = POP_W(); if (cpu_state.abrt) return 1; \ - loadseg(temp_seg, realseg); if (cpu_state.abrt) ESP = temp_esp; \ - CLOCK_CYCLES(is486 ? 3 : 7); \ - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } \ - static int opPOP_ ## seg ## _l(uint32_t fetchdat) \ - { \ - uint32_t temp_seg; \ - uint32_t temp_esp = ESP; \ - temp_seg = POP_L(); if (cpu_state.abrt) return 1; \ - loadseg(temp_seg & 0xffff, realseg); if (cpu_state.abrt) ESP = temp_esp; \ - CLOCK_CYCLES(is486 ? 3 : 7); \ - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ + PUSH_W(frame_ptr); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; } + CLOCK_CYCLES((is486) ? 3 : 5); +#ifndef IS_DYNAREC + writes++; + instr_cycles += (is486) ? 3 : 5; +#endif + } + BP = frame_ptr; + if (stack32) + ESP -= offset; + else + SP -= offset; + CLOCK_CYCLES((is486) ? 14 : 10); +#ifndef IS_DYNAREC + instr_cycles += (is486) ? 14 : 10; + PREFETCH_RUN(instr_cycles, 3, -1, reads, 0, writes, 0, 0); +#endif + return 0; +} +static int +opENTER_l(uint32_t fetchdat) +{ + uint16_t offset; + int count; + uint32_t tempEBP, tempESP, frame_ptr; +#ifndef IS_DYNAREC + int reads = 0, writes = 1, instr_cycles = 0; +#endif + uint32_t templ; + + offset = getwordf(); + count = (fetchdat >> 16) & 0xff; + cpu_state.pc++; + tempEBP = EBP; + tempESP = ESP; + + PUSH_L(EBP); + if (cpu_state.abrt) + return 1; + frame_ptr = ESP; + + if (count > 0) { + while (--count) { + EBP -= 4; + templ = readmeml(ss, EBP); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + PUSH_L(templ); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 4); +#ifndef IS_DYNAREC + reads++; + writes++; + instr_cycles += (is486) ? 3 : 4; +#endif + } + PUSH_L(frame_ptr); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 5); +#ifndef IS_DYNAREC + writes++; + instr_cycles += (is486) ? 3 : 5; +#endif + } + EBP = frame_ptr; + + if (stack32) + ESP -= offset; + else + SP -= offset; + CLOCK_CYCLES((is486) ? 14 : 10); +#ifndef IS_DYNAREC + instr_cycles += (is486) ? 14 : 10; + PREFETCH_RUN(instr_cycles, 3, -1, reads, 0, writes, 0, 0); +#endif + return 0; +} + +static int +opLEAVE_w(uint32_t fetchdat) +{ + uint32_t tempESP = ESP; + uint16_t temp; + + SP = BP; + temp = POP_W(); + if (cpu_state.abrt) { + ESP = tempESP; + return 1; + } + BP = temp; + + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opLEAVE_l(uint32_t fetchdat) +{ + uint32_t tempESP = ESP; + uint32_t temp; + + ESP = EBP; + temp = POP_L(); + if (cpu_state.abrt) { + ESP = tempESP; + return 1; + } + EBP = temp; + + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 1, 0, 0, 0); + return 0; +} + +#define PUSH_SEG_OPS(seg) \ + static int opPUSH_##seg##_w(uint32_t fetchdat) \ + { \ + PUSH_W(seg); \ + CLOCK_CYCLES(2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } \ + static int opPUSH_##seg##_l(uint32_t fetchdat) \ + { \ + PUSH_L(seg); \ + CLOCK_CYCLES(2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 1, 0); \ + return cpu_state.abrt; \ + } + +#define POP_SEG_OPS(seg, realseg) \ + static int opPOP_##seg##_w(uint32_t fetchdat) \ + { \ + uint16_t temp_seg; \ + uint32_t temp_esp = ESP; \ + temp_seg = POP_W(); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(temp_seg, realseg); \ + if (cpu_state.abrt) \ + ESP = temp_esp; \ + CLOCK_CYCLES(is486 ? 3 : 7); \ + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } \ + static int opPOP_##seg##_l(uint32_t fetchdat) \ + { \ + uint32_t temp_seg; \ + uint32_t temp_esp = ESP; \ + temp_seg = POP_L(); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(temp_seg & 0xffff, realseg); \ + if (cpu_state.abrt) \ + ESP = temp_esp; \ + CLOCK_CYCLES(is486 ? 3 : 7); \ + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } PUSH_SEG_OPS(CS) PUSH_SEG_OPS(DS) @@ -497,44 +607,59 @@ POP_SEG_OPS(ES, &cpu_state.seg_es) POP_SEG_OPS(FS, &cpu_state.seg_fs) POP_SEG_OPS(GS, &cpu_state.seg_gs) - -static int opPOP_SS_w(uint32_t fetchdat) +static int +opPOP_SS_w(uint32_t fetchdat) { - uint16_t temp_seg; - uint32_t temp_esp = ESP; - temp_seg = POP_W(); if (cpu_state.abrt) return 1; - loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } - CLOCK_CYCLES(is486 ? 3 : 7); - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - + uint16_t temp_seg; + uint32_t temp_esp = ESP; + temp_seg = POP_W(); + if (cpu_state.abrt) return 1; + loadseg(temp_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) { + ESP = temp_esp; + return 1; + } + CLOCK_CYCLES(is486 ? 3 : 7); + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); + + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + + return 1; } -static int opPOP_SS_l(uint32_t fetchdat) +static int +opPOP_SS_l(uint32_t fetchdat) { - uint32_t temp_seg; - uint32_t temp_esp = ESP; - temp_seg = POP_L(); if (cpu_state.abrt) return 1; - loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } - CLOCK_CYCLES(is486 ? 3 : 7); - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - + uint32_t temp_seg; + uint32_t temp_esp = ESP; + temp_seg = POP_L(); + if (cpu_state.abrt) return 1; + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); + if (cpu_state.abrt) { + ESP = temp_esp; + return 1; + } + CLOCK_CYCLES(is486 ? 3 : 7); + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); + + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + + return 1; } diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index 54a22d4b8..5cc5f3806 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -1,792 +1,1095 @@ -static int opMOVSB_a16(uint32_t fetchdat) +static int +opMOVSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - high_page = 0; - do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); - do_mmut_wb(es, DI, &addr64_2); - if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; - writememb_n(es, DI, addr64_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); - return 0; + do_mmut_wb(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, DI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opMOVSB_a32(uint32_t fetchdat) +static int +opMOVSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - high_page = 0; - do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); - do_mmut_wb(es, EDI, &addr64_2); - if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; - writememb_n(es, EDI, addr64_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + do_mmut_wb(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, EDI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opMOVSW_a16(uint32_t fetchdat) +static int +opMOVSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - high_page = 0; - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); - do_mmut_ww(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - writememw_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + do_mmut_ww(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opMOVSW_a32(uint32_t fetchdat) +static int +opMOVSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - high_page = 0; - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); - do_mmut_ww(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - writememw_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_ww(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opMOVSL_a16(uint32_t fetchdat) +static int +opMOVSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - high_page = 0; - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); - do_mmut_wl(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - writememl_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,1, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + do_mmut_wl(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 0); + return 0; } -static int opMOVSL_a32(uint32_t fetchdat) +static int +opMOVSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - high_page = 0; - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); - do_mmut_wl(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - writememl_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,1, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + do_mmut_wl(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 1); + return 0; } - -static int opCMPSB_a16(uint32_t fetchdat) +static int +opCMPSB_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - high_page = uncached = 0; - do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI); - do_mmut_rb2(es, DI, &addr64_2); - if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; - dst = readmemb_n(es, DI, addr64_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; - setsub8(src, dst); - if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI); + do_mmut_rb2(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = old_rl2; + dst = readmemb_n(es, DI, addr64_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; } -static int opCMPSB_a32(uint32_t fetchdat) +static int +opCMPSB_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - high_page = uncached = 0; - do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI); - do_mmut_rb2(es, EDI, &addr64_2); - if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; - dst = readmemb_n(es, EDI, addr64_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; - setsub8(src, dst); - if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + do_mmut_rb2(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = old_rl2; + dst = readmemb_n(es, EDI, addr64_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; } -static int opCMPSW_a16(uint32_t fetchdat) +static int +opCMPSW_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - high_page = uncached = 0; - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); - do_mmut_rw2(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; - dst = readmemw_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; - setsub16(src, dst); - if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + do_mmut_rw2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = old_rl2; + dst = readmemw_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; } -static int opCMPSW_a32(uint32_t fetchdat) +static int +opCMPSW_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - high_page = uncached = 0; - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); - do_mmut_rw2(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; - dst = readmemw_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; - setsub16(src, dst); - if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_rw2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = old_rl2; + dst = readmemw_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; } -static int opCMPSL_a16(uint32_t fetchdat) +static int +opCMPSL_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - high_page = uncached = 0; - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); - do_mmut_rl2(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; - dst = readmeml_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; - setsub32(src, dst); - if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + do_mmut_rl2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = old_rl2; + dst = readmeml_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 0); + return 0; } -static int opCMPSL_a32(uint32_t fetchdat) +static int +opCMPSL_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - high_page = uncached = 0; - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); - do_mmut_rl2(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; - dst = readmeml_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; - setsub32(src, dst); - if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + do_mmut_rl2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = old_rl2; + dst = readmeml_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 1); + return 0; } -static int opSTOSB_a16(uint32_t fetchdat) +static int +opSTOSB_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI); - writememb(es, DI, AL); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + writememb(es, DI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; } -static int opSTOSB_a32(uint32_t fetchdat) +static int +opSTOSB_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); - writememb(es, EDI, AL); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + writememb(es, EDI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; } -static int opSTOSW_a16(uint32_t fetchdat) +static int +opSTOSW_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); - writememw(es, DI, AX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + writememw(es, DI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; } -static int opSTOSW_a32(uint32_t fetchdat) +static int +opSTOSW_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); - writememw(es, EDI, AX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + writememw(es, EDI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; } -static int opSTOSL_a16(uint32_t fetchdat) +static int +opSTOSL_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); - writememl(es, DI, EAX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + writememl(es, DI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return 0; } -static int opSTOSL_a32(uint32_t fetchdat) +static int +opSTOSL_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); - writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + writememl(es, EDI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 1); + return 0; } - -static int opLODSB_a16(uint32_t fetchdat) +static int +opLODSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - AL = temp; - if (cpu_state.flags & D_FLAG) SI--; - else SI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opLODSB_a32(uint32_t fetchdat) +static int +opLODSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - AL = temp; - if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opLODSW_a16(uint32_t fetchdat) +static int +opLODSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - AX = temp; - if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opLODSW_a32(uint32_t fetchdat) +static int +opLODSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - AX = temp; - if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opLODSL_a16(uint32_t fetchdat) +static int +opLODSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - EAX = temp; - if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); + return 0; } -static int opLODSL_a32(uint32_t fetchdat) +static int +opLODSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - EAX = temp; - if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 1); + return 0; } - -static int opSCASB_a16(uint32_t fetchdat) +static int +opSCASB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI); - temp = readmemb(es, DI); if (cpu_state.abrt) return 1; - setsub8(AL, temp); - if (cpu_state.flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI); + temp = readmemb(es, DI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opSCASB_a32(uint32_t fetchdat) +static int +opSCASB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI); - temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; - setsub8(AL, temp); - if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + temp = readmemb(es, EDI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opSCASW_a16(uint32_t fetchdat) +static int +opSCASW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); - temp = readmemw(es, DI); if (cpu_state.abrt) return 1; - setsub16(AX, temp); - if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + temp = readmemw(es, DI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opSCASW_a32(uint32_t fetchdat) +static int +opSCASW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); - temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; - setsub16(AX, temp); - if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + temp = readmemw(es, EDI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opSCASL_a16(uint32_t fetchdat) +static int +opSCASL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); - temp = readmeml(es, DI); if (cpu_state.abrt) return 1; - setsub32(EAX, temp); - if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + temp = readmeml(es, DI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 0); + return 0; } -static int opSCASL_a32(uint32_t fetchdat) +static int +opSCASL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); - temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; - setsub32(EAX, temp); - if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + temp = readmeml(es, EDI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 1); + return 0; } -static int opINSB_a16(uint32_t fetchdat) +static int +opINSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = 0x00000000; + addr64 = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - CHECK_WRITE(&cpu_state.seg_es, DI, DI); - high_page = 0; - do_mmut_wb(es, DI, &addr64); if (cpu_state.abrt) return 1; - temp = inb(DX); - writememb_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + high_page = 0; + do_mmut_wb(es, DI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, DI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opINSB_a32(uint32_t fetchdat) +static int +opINSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = 0x00000000; + addr64 = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - high_page = 0; - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); - do_mmut_wb(es, EDI, &addr64); if (cpu_state.abrt) return 1; - temp = inb(DX); - writememb_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + high_page = 0; + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + do_mmut_wb(es, EDI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, EDI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opINSW_a16(uint32_t fetchdat) +static int +opINSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); - high_page = 0; - do_mmut_ww(es, DI, addr64a); if (cpu_state.abrt) return 1; - temp = inw(DX); - writememw_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + high_page = 0; + do_mmut_ww(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opINSW_a32(uint32_t fetchdat) +static int +opINSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - high_page = 0; - check_io_perm(DX); - check_io_perm(DX + 1); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); - do_mmut_ww(es, EDI, addr64a); if (cpu_state.abrt) return 1; - temp = inw(DX); - writememw_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + high_page = 0; + check_io_perm(DX); + check_io_perm(DX + 1); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_ww(es, EDI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opINSL_a16(uint32_t fetchdat) +static int +opINSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); - high_page = 0; - do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; - temp = inl(DX); - writememl_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0,1,0,1, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 0); + return 0; } -static int opINSL_a32(uint32_t fetchdat) +static int +opINSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); - high_page = 0; - do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; - temp = inl(DX); - writememl_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0,1,0,1, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 1); + return 0; } -static int opOUTSB_a16(uint32_t fetchdat) +static int +opOUTSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - if (cpu_state.flags & D_FLAG) SI--; - else SI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opOUTSB_a32(uint32_t fetchdat) +static int +opOUTSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opOUTSW_a16(uint32_t fetchdat) +static int +opOUTSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; - outw(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opOUTSW_a32(uint32_t fetchdat) +static int +opOUTSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; - outw(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opOUTSL_a16(uint32_t fetchdat) +static int +opOUTSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; - outl(EDX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 0,1,0,1, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 0); + return 0; } -static int opOUTSL_a32(uint32_t fetchdat) +static int +opOUTSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; - outl(EDX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 0,1,0,1, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 1); + return 0; } diff --git a/src/cpu/x86_ops_xchg.h b/src/cpu/x86_ops_xchg.h index 300e97f25..c5ce08999 100644 --- a/src/cpu/x86_ops_xchg.h +++ b/src/cpu/x86_ops_xchg.h @@ -1,229 +1,272 @@ -static int opXCHG_b_a16(uint32_t fetchdat) +static int +opXCHG_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + seteab(getr8(cpu_reg)); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opXCHG_b_a32(uint32_t fetchdat) +static int +opXCHG_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + seteab(getr8(cpu_reg)); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return 0; } -static int opXCHG_w_a16(uint32_t fetchdat) +static int +opXCHG_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + seteaw(cpu_state.regs[cpu_reg].w); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opXCHG_w_a32(uint32_t fetchdat) +static int +opXCHG_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + seteaw(cpu_state.regs[cpu_reg].w); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return 0; } -static int opXCHG_l_a16(uint32_t fetchdat) +static int +opXCHG_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + seteal(cpu_state.regs[cpu_reg].l); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + return 0; } -static int opXCHG_l_a32(uint32_t fetchdat) +static int +opXCHG_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + seteal(cpu_state.regs[cpu_reg].l); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + return 0; } - -static int opXCHG_AX_BX(uint32_t fetchdat) +static int +opXCHG_AX_BX(uint32_t fetchdat) { - uint16_t temp = AX; - AX = BX; - BX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = BX; + BX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_CX(uint32_t fetchdat) +static int +opXCHG_AX_CX(uint32_t fetchdat) { - uint16_t temp = AX; - AX = CX; - CX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = CX; + CX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_DX(uint32_t fetchdat) +static int +opXCHG_AX_DX(uint32_t fetchdat) { - uint16_t temp = AX; - AX = DX; - DX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = DX; + DX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_SI(uint32_t fetchdat) +static int +opXCHG_AX_SI(uint32_t fetchdat) { - uint16_t temp = AX; - AX = SI; - SI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = SI; + SI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_DI(uint32_t fetchdat) +static int +opXCHG_AX_DI(uint32_t fetchdat) { - uint16_t temp = AX; - AX = DI; - DI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = DI; + DI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_BP(uint32_t fetchdat) +static int +opXCHG_AX_BP(uint32_t fetchdat) { - uint16_t temp = AX; - AX = BP; - BP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = BP; + BP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_SP(uint32_t fetchdat) +static int +opXCHG_AX_SP(uint32_t fetchdat) { - uint16_t temp = AX; - AX = SP; - SP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = SP; + SP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EBX(uint32_t fetchdat) +static int +opXCHG_EAX_EBX(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EBX; - EBX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EBX; + EBX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_ECX(uint32_t fetchdat) +static int +opXCHG_EAX_ECX(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = ECX; - ECX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = ECX; + ECX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EDX(uint32_t fetchdat) +static int +opXCHG_EAX_EDX(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EDX; - EDX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EDX; + EDX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_ESI(uint32_t fetchdat) +static int +opXCHG_EAX_ESI(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = ESI; - ESI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = ESI; + ESI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EDI(uint32_t fetchdat) +static int +opXCHG_EAX_EDI(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EDI; - EDI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EDI; + EDI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EBP(uint32_t fetchdat) +static int +opXCHG_EAX_EBP(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EBP; - EBP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EBP; + EBP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_ESP(uint32_t fetchdat) +static int +opXCHG_EAX_ESP(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = ESP; - ESP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = ESP; + ESP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } +#define opBSWAP(reg) \ + static int opBSWAP_##reg(uint32_t fetchdat) \ + { \ + reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \ + CLOCK_CYCLES(1); \ + PREFETCH_RUN(1, 1, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } -#define opBSWAP(reg) \ - static int opBSWAP_ ## reg(uint32_t fetchdat) \ - { \ - reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \ - CLOCK_CYCLES(1); \ - PREFETCH_RUN(1, 1, -1, 0,0,0,0, 0); \ - return 0; \ - } - +// clang-format off opBSWAP(EAX) opBSWAP(EBX) opBSWAP(ECX) @@ -232,3 +275,4 @@ opBSWAP(ESI) opBSWAP(EDI) opBSWAP(EBP) opBSWAP(ESP) +// clang-format on diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 6737133ed..c1e9e5b3d 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * x86 CPU segment emulation. + * x86 CPU segment emulation. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -35,7 +35,6 @@ #include "x86_flags.h" #include "386_common.h" - uint8_t opcode2; int cgate16, cgate32; @@ -45,56 +44,52 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); void pmodeint(int num, int soft); -#define DPL ((segdat[2] >> 13) & 3) +#define DPL ((segdat[2] >> 13) & 3) #define DPL2 ((segdat2[2] >> 13) & 3) #define DPL3 ((segdat3[2] >> 13) & 3) - #ifdef ENABLE_X86SEG_LOG int x86seg_do_log = ENABLE_X86SEG_LOG; - static void x86seg_log(const char *fmt, ...) { va_list ap; if (x86seg_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x86seg_log(fmt, ...) +# define x86seg_log(fmt, ...) #endif - static void seg_reset(x86seg *s) { - s->access = 0x82; - s->ar_high = 0x10; - s->limit = 0xffff; - s->limit_low = 0; + s->access = 0x82; + s->ar_high = 0x10; + s->limit = 0xffff; + s->limit_low = 0; s->limit_high = 0xffff; if (s == &cpu_state.seg_cs) { - if (!cpu_inited) - fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n"); - if (is6117) - s->base = 0x03ff0000; - else - s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; - s->seg = is286 ? 0xf000 : 0xffff; + if (!cpu_inited) + fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n"); + if (is6117) + s->base = 0x03ff0000; + else + s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; + s->seg = is286 ? 0xf000 : 0xffff; } else { - s->base = 0; - s->seg = 0; + s->base = 0; + s->seg = 0; } } - void -x86seg_reset() +x86seg_reset(void) { seg_reset(&cpu_state.seg_cs); seg_reset(&cpu_state.seg_ds); @@ -104,239 +99,234 @@ x86seg_reset() seg_reset(&cpu_state.seg_ss); } - void x86_doabrt(int x86_abrt) { #ifndef USE_NEW_DYNAREC CS = oldcs; #endif - cpu_state.pc = cpu_state.oldpc; - cpu_state.seg_cs.access = (oldcpl << 5) | 0x80; + cpu_state.pc = cpu_state.oldpc; + cpu_state.seg_cs.access = (oldcpl << 5) | 0x80; cpu_state.seg_cs.ar_high = 0x10; if (msw & 1) - pmodeint(x86_abrt, 0); + pmodeint(x86_abrt, 0); else { - uint32_t addr = (x86_abrt << 2) + idt.base; - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xffff), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xffff), CS); - writememw(ss, ((SP - 6) & 0xffff), cpu_state.pc); - SP -= 6; - } + uint32_t addr = (x86_abrt << 2) + idt.base; + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xffff), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xffff), CS); + writememw(ss, ((SP - 6) & 0xffff), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~(I_FLAG | T_FLAG); + cpu_state.flags &= ~(I_FLAG | T_FLAG); #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - return; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + return; } if (cpu_state.abrt || x86_was_reset) - return; + return; if (intgatesize == 16) { - if (stack32) { - writememw(ss, ESP - 2, abrt_error); - ESP -= 2; - } else { - writememw(ss, ((SP - 2) & 0xffff), abrt_error); - SP -= 2; - } + if (stack32) { + writememw(ss, ESP - 2, abrt_error); + ESP -= 2; + } else { + writememw(ss, ((SP - 2) & 0xffff), abrt_error); + SP -= 2; + } } else { - if (stack32) { - writememl(ss, ESP - 4, abrt_error); - ESP -= 4; - } else { - writememl(ss, ((SP - 4) & 0xffff), abrt_error); - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, abrt_error); + ESP -= 4; + } else { + writememl(ss, ((SP - 4) & 0xffff), abrt_error); + SP -= 4; + } } } - void x86de(char *s, uint16_t error) { #ifdef BAD_CODE cpu_state.abrt = ABRT_DE; - abrt_error = error; + abrt_error = error; #else x86_int(0); #endif } - void x86gpf(char *s, uint16_t error) { cpu_state.abrt = ABRT_GPF; - abrt_error = error; + abrt_error = error; } - void x86gpf_expected(char *s, uint16_t error) { cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; - abrt_error = error; + abrt_error = error; } - void x86ss(char *s, uint16_t error) { cpu_state.abrt = ABRT_SS; - abrt_error = error; + abrt_error = error; } - -void x86ts(char *s, uint16_t error) +void +x86ts(char *s, uint16_t error) { cpu_state.abrt = ABRT_TS; - abrt_error = error; + abrt_error = error; } - void x86np(char *s, uint16_t error) { cpu_state.abrt = ABRT_NP; - abrt_error = error; + abrt_error = error; } - static void set_stack32(int s) { stack32 = s; if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; + cpu_cur_status |= CPU_STATUS_STACK32; else - cpu_cur_status &= ~CPU_STATUS_STACK32; + cpu_cur_status &= ~CPU_STATUS_STACK32; } - static void set_use32(int u) { use32 = u ? 0x300 : 0; if (u) - cpu_cur_status |= CPU_STATUS_USE32; + cpu_cur_status |= CPU_STATUS_USE32; else - cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_cur_status &= ~CPU_STATUS_USE32; } - void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0x000f) << 16); if (segdat[3] & 0x0080) - s->limit = (s->limit << 12) | 0xfff; + s->limit = (s->limit << 12) | 0xfff; s->base = segdat[1] | ((segdat[2] & 0x00ff) << 16); if (is386) - s->base |= ((segdat[3] >> 8) << 24); - s->access = segdat[2] >> 8; + s->base |= ((segdat[3] >> 8) << 24); + s->access = segdat[2] >> 8; s->ar_high = segdat[3] & 0xff; if (((segdat[2] & 0x1800) != 0x1000) || !(segdat[2] & (1 << 10))) { - /* Expand-down */ - s->limit_high = s->limit; - s->limit_low = 0; + /* Expand-down */ + s->limit_high = s->limit; + s->limit_low = 0; } else { - s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; + s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; + s->limit_low = s->limit + 1; } if (s == &cpu_state.seg_ds) { - if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &cpu_state.seg_ss) { - if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; + if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } - static void do_seg_v86_init(x86seg *s) { - s->access = 0xe2; - s->ar_high = 0x10; - s->limit = 0xffff; - s->limit_low = 0; + s->access = 0xe2; + s->ar_high = 0x10; + s->limit = 0xffff; + s->limit_low = 0; s->limit_high = 0xffff; } - static void check_seg_valid(x86seg *s) { - int dpl = (s->access >> 5) & 3; - int valid = 1; - x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; + int dpl = (s->access >> 5) & 3; + int valid = 1; + x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; if (((s->seg & 0xfff8UL) + 7UL) > dt->limit) - valid = 0; + valid = 0; switch (s->access & 0x1f) { - case 0x10: case 0x11: case 0x12: case 0x13: /* Data segments */ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1a: case 0x1b: /* Readable non-conforming code */ - if (((s->seg & 3) > dpl) || ((CPL) > dpl)) { - valid = 0; - break; - } - break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: /* Data segments */ + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x1a: + case 0x1b: /* Readable non-conforming code */ + if (((s->seg & 3) > dpl) || ((CPL) > dpl)) { + valid = 0; + break; + } + break; - case 0x1e: case 0x1f: /* Readable conforming code */ - break; + case 0x1e: + case 0x1f: /* Readable conforming code */ + break; - default: - valid = 0; - break; + default: + valid = 0; + break; } if (!valid) - loadseg(0, s); + loadseg(0, s); } - static void read_descriptor(uint32_t addr, uint16_t *segdat, uint32_t *segdat32, int override) { if (override) - cpl_override = 1; + cpl_override = 1; if (cpu_16bitbus) { - segdat[0] = readmemw(0, addr); - segdat[1] = readmemw(0, addr + 2); - segdat[2] = readmemw(0, addr + 4); - segdat[3] = readmemw(0, addr + 6); + segdat[0] = readmemw(0, addr); + segdat[1] = readmemw(0, addr + 2); + segdat[2] = readmemw(0, addr + 4); + segdat[3] = readmemw(0, addr + 6); } else { - segdat32[0] = readmeml(0, addr); - segdat32[1] = readmeml(0, addr + 4); + segdat32[0] = readmeml(0, addr); + segdat32[1] = readmeml(0, addr + 4); } if (override) - cpl_override = 0; + cpl_override = 0; } - #ifdef USE_NEW_DYNAREC int #else @@ -346,180 +336,191 @@ loadseg(uint16_t seg, x86seg *s) { uint16_t segdat[4]; uint32_t addr, *segdat32 = (uint32_t *) segdat; - int dpl; - x86seg *dt; + int dpl; + x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & 0xfffc)) { - if (s == &cpu_state.seg_ss) { - x86ss(NULL,0); + if (!(seg & 0xfffc)) { + if (s == &cpu_state.seg_ss) { + x86ss(NULL, 0); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - s->seg = 0; - s->access = 0x80; - s->ar_high = 0x10; - s->base = -1; - if (s == &cpu_state.seg_ds) - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + } + s->seg = 0; + s->access = 0x80; + s->ar_high = 0x10; + s->base = -1; + if (s == &cpu_state.seg_ds) + cpu_cur_status |= CPU_STATUS_NOTFLATDS; #ifdef USE_NEW_DYNAREC - return 0; + return 0; #else - return; + return; #endif - } - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadseg(): Bigger than LDT limit", seg & 0xfffc); + } + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadseg(): Bigger than LDT limit", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - dpl = (segdat[2] >> 13) & 3; - if (s == &cpu_state.seg_ss) { - if (!(seg & 0xfffc)) { - x86gpf("loadseg(): Zero stack segment", seg & 0xfffc); + dpl = (segdat[2] >> 13) & 3; + if (s == &cpu_state.seg_ss) { + if (!(seg & 0xfffc)) { + x86gpf("loadseg(): Zero stack segment", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if ((seg & 0x0003) != CPL) { - x86gpf("loadseg(): Stack segment RPL != CPL", seg & 0xfffc); + } + if ((seg & 0x0003) != CPL) { + x86gpf("loadseg(): Stack segment RPL != CPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if (dpl != CPL) { - x86gpf("loadseg(): Stack segment DPL != CPL", seg & 0xfffc); + } + if (dpl != CPL) { + x86gpf("loadseg(): Stack segment DPL != CPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - switch ((segdat[2] >> 8) & 0x1f) { - case 0x12: case 0x13: case 0x16: case 0x17: - /* R/W */ - break; - default: - x86gpf("loadseg(): Unknown stack segment type", seg & ~3); + } + switch ((segdat[2] >> 8) & 0x1f) { + case 0x12: + case 0x13: + case 0x16: + case 0x17: + /* R/W */ + break; + default: + x86gpf("loadseg(): Unknown stack segment type", seg & ~3); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if (!(segdat[2] & 0x8000)) { - x86ss(NULL, seg & 0xfffc); + } + if (!(segdat[2] & 0x8000)) { + x86ss(NULL, seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - set_stack32((segdat[3] & 0x40) ? 1 : 0); - } else if (s != &cpu_state.seg_cs) { - x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - x86seg_log("Seg type %03X\n",segdat[2] & 0x1f00); - switch ((segdat[2] >> 8) & 0x1f) { - case 0x10: case 0x11: case 0x12: case 0x13: /* Data segments */ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1a: case 0x1b: /* Readable non-conforming code */ - if ((seg & 0x0003) > dpl) { - x86gpf("loadseg(): Normal segment RPL > DPL", seg & 0xfffc); + } + set_stack32((segdat[3] & 0x40) ? 1 : 0); + } else if (s != &cpu_state.seg_cs) { + x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); + x86seg_log("Seg type %03X\n", segdat[2] & 0x1f00); + switch ((segdat[2] >> 8) & 0x1f) { + case 0x10: + case 0x11: + case 0x12: + case 0x13: /* Data segments */ + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x1a: + case 0x1b: /* Readable non-conforming code */ + if ((seg & 0x0003) > dpl) { + x86gpf("loadseg(): Normal segment RPL > DPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if ((CPL) > dpl) { - x86gpf("loadseg(): Normal segment DPL < CPL", seg& 0xfffc); + } + if ((CPL) > dpl) { + x86gpf("loadseg(): Normal segment DPL < CPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - break; - case 0x1e: case 0x1f: /* Readable conforming code */ - break; - default: - x86gpf("loadseg(): Unknown normal segment type", seg & 0xfffc); + } + break; + case 0x1e: + case 0x1f: /* Readable conforming code */ + break; + default: + x86gpf("loadseg(): Unknown normal segment type", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - } + } + } - if (!(segdat[2] & 0x8000)) { - x86np("Load data seg not present", seg & 0xfffc); + if (!(segdat[2] & 0x8000)) { + x86np("Load data seg not present", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - s->seg = seg; - do_seg_load(s, segdat); + } + s->seg = seg; + do_seg_load(s, segdat); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - s->checked = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + s->checked = 0; #ifdef USE_DYNAREC - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; + if (s == &cpu_state.seg_ds) + codegen_flat_ds = 0; + if (s == &cpu_state.seg_ss) + codegen_flat_ss = 0; #endif } else { - s->access = 0xe2; - s->ar_high = 0x10; - s->base = seg << 4; - s->seg = seg; - s->checked = 1; + s->access = 0xe2; + s->ar_high = 0x10; + s->base = seg << 4; + s->seg = seg; + s->checked = 1; #ifdef USE_DYNAREC - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; + if (s == &cpu_state.seg_ds) + codegen_flat_ds = 0; + if (s == &cpu_state.seg_ss) + codegen_flat_ss = 0; #endif - if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) - set_stack32(0); + if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) + set_stack32(0); } if (s == &cpu_state.seg_ds) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &cpu_state.seg_ss) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } #ifdef USE_NEW_DYNAREC @@ -527,1884 +528,1922 @@ loadseg(uint16_t seg, x86seg *s) #endif } - void loadcs(uint16_t seg) { uint16_t segdat[4]; uint32_t addr, *segdat32 = (uint32_t *) segdat; - x86seg *dt; + x86seg *dt; x86seg_log("Load CS %04X\n", seg); if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & 0xfffc)) { - x86gpf("loadcs(): Protected mode selector is zero", 0); - return; - } + if (!(seg & 0xfffc)) { + x86gpf("loadcs(): Protected mode selector is zero", 0); + return; + } - addr = seg & 0xfff8; - dt = (seg & 0x0004)? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcs(): Protected mode selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcs(): Protected mode selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; - if (segdat[2] & 0x1000) { - /* Normal code segment */ - if (!(segdat[2] & 0x0400)) { - /* Not conforming */ - if ((seg & 3) > CPL) { - x86gpf("loadcs(): Non-conforming RPL > CPL", seg & 0xfffc); - return; - } - if (CPL != DPL) { - x86gpf("loadcs(): Non-conforming CPL != DPL", seg & 0xfffc); - return; - } - } - if (CPL < DPL) { - x86gpf("loadcs(): CPL < DPL", seg & ~3); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x40); - CS = (seg & 0xfffc) | CPL; - do_seg_load(&cpu_state.seg_cs, segdat); - use32 = (segdat[3] & 0x40) ? 0x300 : 0; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; + if (segdat[2] & 0x1000) { + /* Normal code segment */ + if (!(segdat[2] & 0x0400)) { + /* Not conforming */ + if ((seg & 3) > CPL) { + x86gpf("loadcs(): Non-conforming RPL > CPL", seg & 0xfffc); + return; + } + if (CPL != DPL) { + x86gpf("loadcs(): Non-conforming CPL != DPL", seg & 0xfffc); + return; + } + } + if (CPL < DPL) { + x86gpf("loadcs(): CPL < DPL", seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS not present", seg & 0xfffc); + return; + } + set_use32(segdat[3] & 0x40); + CS = (seg & 0xfffc) | CPL; + do_seg_load(&cpu_state.seg_cs, segdat); + use32 = (segdat[3] & 0x40) ? 0x300 : 0; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ - cpl_override = 0; - } else { - /* System segment */ - if (!(segdat[2] & 0x8000)) { - x86np("Load CS system seg not present", seg & 0xfffc); - return; - } - switch (segdat[2] & 0x0f00) { - default: - x86gpf("Load CS system segment has bits 0-3 of access rights set", seg & 0xfffc); - return; - } - } + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ + cpl_override = 0; + } else { + /* System segment */ + if (!(segdat[2] & 0x8000)) { + x86np("Load CS system seg not present", seg & 0xfffc); + return; + } + switch (segdat[2] & 0x0f00) { + default: + x86gpf("Load CS system segment has bits 0-3 of access rights set", seg & 0xfffc); + return; + } + } } else { - cpu_state.seg_cs.base = (seg << 4); - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.seg = seg & 0xffff; - cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.seg_cs.base = (seg << 4); + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.seg = seg & 0xffff; + cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif } } - void loadcsjmp(uint16_t seg, uint32_t old_pc) { - uint16_t type, seg2; - uint16_t segdat[4]; - uint32_t addr, newpc; + uint16_t type, seg2; + uint16_t segdat[4]; + uint32_t addr, newpc; uint32_t *segdat32 = (uint32_t *) segdat; - x86seg *dt; + x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & 0xfffc)) { - x86gpf("loadcsjmp(): Selector is zero", 0); - return; - } - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loacsjmp(): Selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; - x86seg_log("%04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - if (segdat[2] & 0x1000) { - /* Normal code segment */ - if (!(segdat[2] & 0x0400)) { - /* Not conforming */ - if ((seg & 0x0003) > CPL) { - x86gpf("loadcsjmp(): segment PL > CPL", seg & 0xfffc); - return; - } - if (CPL != DPL) { - x86gpf("loadcsjmp(): CPL != DPL", seg & 0xfffc); - return; - } - } - if (CPL < DPL) { - x86gpf("loadcsjmp(): CPL < DPL",seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x0040); + if (!(seg & 0xfffc)) { + x86gpf("loadcsjmp(): Selector is zero", 0); + return; + } + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loacsjmp(): Selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; + x86seg_log("%04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); + if (segdat[2] & 0x1000) { + /* Normal code segment */ + if (!(segdat[2] & 0x0400)) { + /* Not conforming */ + if ((seg & 0x0003) > CPL) { + x86gpf("loadcsjmp(): segment PL > CPL", seg & 0xfffc); + return; + } + if (CPL != DPL) { + x86gpf("loadcsjmp(): CPL != DPL", seg & 0xfffc); + return; + } + } + if (CPL < DPL) { + x86gpf("loadcsjmp(): CPL < DPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP not present", seg & 0xfffc); + return; + } + set_use32(segdat[3] & 0x0040); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ + cpl_override = 0; - CS = (seg & 0xfffc) | CPL; - segdat[2] = (segdat[2] & ~(3 << 13)) | (CPL << 13); + CS = (seg & 0xfffc) | CPL; + segdat[2] = (segdat[2] & ~(3 << 13)) | (CPL << 13); - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - cycles -= timing_jmp_pm; - } else { /* System segment */ - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP system selector not present", seg & 0xfffc); - return; - } - type = segdat[2] & 0x0f00; - newpc = segdat[0]; - if (type & 0x0800) - newpc |= (segdat[3] << 16); - switch (type) { - case 0x0400: /* Call gate */ - case 0x0c00: - cgate32 = (type & 0x0800); - cgate16 = !cgate32; + cycles -= timing_jmp_pm; + } else { /* System segment */ + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP system selector not present", seg & 0xfffc); + return; + } + type = segdat[2] & 0x0f00; + newpc = segdat[0]; + if (type & 0x0800) + newpc |= (segdat[3] << 16); + switch (type) { + case 0x0400: /* Call gate */ + case 0x0c00: + cgate32 = (type & 0x0800); + cgate16 = !cgate32; #ifndef USE_NEW_DYNAREC - oldcs=CS; + oldcs = CS; #endif - cpu_state.oldpc = cpu_state.pc; - if (DPL < CPL) { - x86gpf("loadcsjmp(): Call gate DPL < CPL",seg & 0xfffc); - return; - } - if (DPL < (seg & 0x0003)) { - x86gpf("loadcsjmp(): Call gate DPL< RPL",seg&~3); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP call gate not present", seg & 0xfffc); - return; - } - seg2 = segdat[1]; + cpu_state.oldpc = cpu_state.pc; + if (DPL < CPL) { + x86gpf("loadcsjmp(): Call gate DPL < CPL", seg & 0xfffc); + return; + } + if (DPL < (seg & 0x0003)) { + x86gpf("loadcsjmp(): Call gate DPL< RPL", seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP call gate not present", seg & 0xfffc); + return; + } + seg2 = segdat[1]; - if (!(seg2 & 0xfffc)) { - x86gpf("Load CS JMP call gate selector is NULL", 0); - return; - } - addr = seg2 & 0xfff8; - dt = (seg2 & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcsjmp(): Call gate selector > DT limit", seg2 & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; + if (!(seg2 & 0xfffc)) { + x86gpf("Load CS JMP call gate selector is NULL", 0); + return; + } + addr = seg2 & 0xfff8; + dt = (seg2 & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcsjmp(): Call gate selector > DT limit", seg2 & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; - if (DPL > CPL) { - x86gpf("loadcsjmp(): ex DPL > CPL",seg2 & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP from call gate not present", seg2 & 0xfffc); - return; - } + if (DPL > CPL) { + x86gpf("loadcsjmp(): ex DPL > CPL", seg2 & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP from call gate not present", seg2 & 0xfffc); + return; + } - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if (DPL > CPL) { - x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc); - return; - } - /*FALLTHROUGH*/ - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming code */ + if (DPL > CPL) { + x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc); + return; + } + /*FALLTHROUGH*/ + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; + set_use32(segdat[3] & 0x40); + cpu_state.pc = newpc; - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - break; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + break; - default: - x86gpf("loadcsjmp(): Unknown type", seg2 & 0xfffc); - return; - } - cycles -= timing_jmp_pm_gate; - break; + default: + x86gpf("loadcsjmp(): Unknown type", seg2 & 0xfffc); + return; + } + cycles -= timing_jmp_pm_gate; + break; - case 0x100: /* 286 Task gate */ - case 0x900: /* 386 Task gate */ - cpu_state.pc = old_pc; - optype = JMP; - cpl_override = 1; - taskswitch286(seg,segdat,segdat[2] & 0x800); - cpu_state.flags &= ~NT_FLAG; - cpl_override=0; - return; + case 0x100: /* 286 Task gate */ + case 0x900: /* 386 Task gate */ + cpu_state.pc = old_pc; + optype = JMP; + cpl_override = 1; + taskswitch286(seg, segdat, segdat[2] & 0x800); + cpu_state.flags &= ~NT_FLAG; + cpl_override = 0; + return; - default: - x86gpf("Load CS JMP call gate selector unknown type", 0); - return; - } - } + default: + x86gpf("Load CS JMP call gate selector unknown type", 0); + return; + } + } } else { - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.seg = seg; - cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.seg = seg; + cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - cycles -= timing_jmp_rm; + cycles -= timing_jmp_rm; } } - void PUSHW(uint16_t v) { if (stack32) { - writememw(ss, ESP - 2, v); - if (cpu_state.abrt) - return; - ESP -= 2; + writememw(ss, ESP - 2, v); + if (cpu_state.abrt) + return; + ESP -= 2; } else { - writememw(ss, ((SP - 2) & 0xffff), v); - if (cpu_state.abrt) - return; - SP -= 2; + writememw(ss, ((SP - 2) & 0xffff), v); + if (cpu_state.abrt) + return; + SP -= 2; } } - void PUSHL(uint32_t v) { if (cpu_16bitbus) { - PUSHW(v >> 16); - PUSHW(v & 0xffff); + PUSHW(v >> 16); + PUSHW(v & 0xffff); } else { - if (stack32) { - writememl(ss, ESP - 4, v); - if (cpu_state.abrt) - return; - ESP -= 4; - } else { - writememl(ss, ((SP - 4) & 0xffff), v); - if (cpu_state.abrt) - return; - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, v); + if (cpu_state.abrt) + return; + ESP -= 4; + } else { + writememl(ss, ((SP - 4) & 0xffff), v); + if (cpu_state.abrt) + return; + SP -= 4; + } } } - uint16_t -POPW() +POPW(void) { uint16_t tempw; if (stack32) { - tempw = readmemw(ss, ESP); - if (cpu_state.abrt) - return 0; - ESP += 2; + tempw = readmemw(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; } else { - tempw = readmemw(ss, SP); - if (cpu_state.abrt) - return 0; - SP += 2; + tempw = readmemw(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 2; } return tempw; } - uint32_t -POPL() +POPL(void) { uint32_t templ; if (cpu_16bitbus) { - templ = POPW(); - templ |= (POPW() << 16); + templ = POPW(); + templ |= (POPW() << 16); } else { - if (stack32) { - templ = readmeml(ss, ESP); - if (cpu_state.abrt) - return 0; - ESP += 4; - } else { - templ = readmeml(ss, SP); - if (cpu_state.abrt) - return 0; - SP += 4; - } + if (stack32) { + templ = readmeml(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + templ = readmeml(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } } return templ; } - #ifdef USE_NEW_DYNAREC -void loadcscall(uint16_t seg, uint32_t old_pc) +void +loadcscall(uint16_t seg, uint32_t old_pc) #else -void loadcscall(uint16_t seg) +void +loadcscall(uint16_t seg) #endif { - uint16_t seg2, newss; - uint16_t segdat[4], segdat2[4]; - uint32_t addr, oldssbase = ss; - uint32_t oaddr, newpc; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t seg2, newss; + uint16_t segdat[4], segdat2[4]; + uint32_t addr, oldssbase = ss; + uint32_t oaddr, newpc; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; - int count, type; - uint32_t oldss, oldsp, newsp, oldsp2; - uint16_t tempw; - x86seg *dt; + int count, type; + uint32_t oldss, oldsp, newsp, oldsp2; + uint16_t tempw; + x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - x86seg_log("Protected mode CS load! %04X\n", seg); - if (!(seg & 0xfffc)) { - x86gpf("loadcscall(): Protected mode selector is zero",0); - return; - } - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcscall(): Selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; - type = segdat[2] & 0x0f00; - newpc = segdat[0]; - if (type & 0x0800) - newpc |= segdat[3] << 16; + x86seg_log("Protected mode CS load! %04X\n", seg); + if (!(seg & 0xfffc)) { + x86gpf("loadcscall(): Protected mode selector is zero", 0); + return; + } + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcscall(): Selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; + type = segdat[2] & 0x0f00; + newpc = segdat[0]; + if (type & 0x0800) + newpc |= segdat[3] << 16; - x86seg_log("Code seg call - %04X - %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2]); - if (segdat[2] & 0x1000) { - if (!(segdat[2] & 0x0400)) { /* Not conforming */ - if ((seg & 0x0003) > CPL) { - x86gpf("loadcscall(): Non-conforming RPL > CPL", seg & 0xfffc); - return; - } - if (CPL != DPL) { - x86gpf("loadcscall(): Non-conforming CPL != DPL", seg & 0xfffc); - return; - } - } - if (CPL < DPL) { - x86gpf("loadcscall(): CPL < DPL", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS call not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x0040); + x86seg_log("Code seg call - %04X - %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2]); + if (segdat[2] & 0x1000) { + if (!(segdat[2] & 0x0400)) { /* Not conforming */ + if ((seg & 0x0003) > CPL) { + x86gpf("loadcscall(): Non-conforming RPL > CPL", seg & 0xfffc); + return; + } + if (CPL != DPL) { + x86gpf("loadcscall(): Non-conforming CPL != DPL", seg & 0xfffc); + return; + } + } + if (CPL < DPL) { + x86gpf("loadcscall(): CPL < DPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS call not present", seg & 0xfffc); + return; + } + set_use32(segdat[3] & 0x0040); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - /* Conforming segments don't change CPL, so preserve existing CPL */ - if (segdat[2] & 0x0400) { - seg = (seg & 0xfffc) | CPL; - segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); - } else /* On non-conforming segments, set RPL = CPL */ - seg = (seg & 0xfffc) | CPL; - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + /* Conforming segments don't change CPL, so preserve existing CPL */ + if (segdat[2] & 0x0400) { + seg = (seg & 0xfffc) | CPL; + segdat[2] = (segdat[2] & ~(3 << (5 + 8))) | (CPL << (5 + 8)); + } else /* On non-conforming segments, set RPL = CPL */ + seg = (seg & 0xfffc) | CPL; + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif #ifdef ENABLE_X86SEG_LOG - x86seg_log("Complete\n"); + x86seg_log("Complete\n"); #endif - cycles -= timing_call_pm; - } else { - type = segdat[2] & 0x0f00; - x86seg_log("Type %03X\n", type); - switch (type) { - case 0x0400: /* Call gate */ - case 0x0c00: /* 386 Call gate */ - x86seg_log("Callgate %08X\n", cpu_state.pc); - cgate32 = (type & 0x0800); - cgate16 = !cgate32; + cycles -= timing_call_pm; + } else { + type = segdat[2] & 0x0f00; + x86seg_log("Type %03X\n", type); + switch (type) { + case 0x0400: /* Call gate */ + case 0x0c00: /* 386 Call gate */ + x86seg_log("Callgate %08X\n", cpu_state.pc); + cgate32 = (type & 0x0800); + cgate16 = !cgate32; #ifndef USE_NEW_DYNAREC - oldcs = CS; + oldcs = CS; #endif - count = segdat[2] & 0x001f; - if (DPL < CPL) { - x86gpf("loadcscall(): ex DPL < CPL",seg & 0xfffc); - return; - } - if (DPL < (seg & 0x0003)) { - x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Call gate not present", seg & 0xfffc); - return; - } - seg2 = segdat[1]; + count = segdat[2] & 0x001f; + if (DPL < CPL) { + x86gpf("loadcscall(): ex DPL < CPL", seg & 0xfffc); + return; + } + if (DPL < (seg & 0x0003)) { + x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Call gate not present", seg & 0xfffc); + return; + } + seg2 = segdat[1]; - x86seg_log("New address : %04X:%08X\n", seg2, newpc); + x86seg_log("New address : %04X:%08X\n", seg2, newpc); - if (!(seg2 & 0xfffc)) { - x86gpf("loadcscall(): ex selector is NULL", 0); - return; - } - addr = seg2 & 0xfff8; - dt = (seg2 & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; + if (!(seg2 & 0xfffc)) { + x86gpf("loadcscall(): ex selector is NULL", 0); + return; + } + addr = seg2 & 0xfff8; + dt = (seg2 & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; - x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]); + x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]); - if (DPL > CPL) { - x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86seg_log("Call gate CS not present %04X\n", seg2); - x86np("Call gate CS not present", seg2 & 0xfffc); - return; - } + if (DPL > CPL) { + x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86seg_log("Call gate CS not present %04X\n", seg2); + x86np("Call gate CS not present", seg2 & 0xfffc); + return; + } - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if (DPL < CPL) { + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming code */ + if (DPL < CPL) { #ifdef USE_NEW_DYNAREC - uint16_t oldcs = CS; + uint16_t oldcs = CS; #endif - oaddr = addr; - /* Load new stack */ - oldss = SS; - oldsp = oldsp2 = ESP; - cpl_override = 1; - if (tr.access & 8) { - addr = 4 + tr.base + (DPL << 3); - newss = readmemw(0, addr + 4); - if (cpu_16bitbus) { - newsp = readmemw(0, addr); - newsp |= (readmemw(0, addr + 2) << 16); - } else - newsp = readmeml(0, addr); - } else { - addr = 2 + tr.base + (DPL * 4); - newss = readmemw(0, addr + 2); - newsp = readmemw(0, addr); - } - cpl_override = 0; - if (cpu_state.abrt) - return; - x86seg_log("New stack %04X:%08X\n", newss, newsp); - if (!(newss & 0xfffc)) { - x86ts(NULL, newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit); - x86ts(NULL, newss & ~3); - return; - } - addr += dt->base; - x86seg_log("Read stack seg\n"); - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - x86seg_log("Read stack seg done!\n"); - if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) { - x86ts(NULL, newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - x86ts("Call gate loading SS unknown type", newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - x86ss("Call gate loading SS not present", newss & 0xfffc); - return; - } - if (!stack32) - oldsp &= 0xffff; - SS = newss; - set_stack32((segdat2[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; + oaddr = addr; + /* Load new stack */ + oldss = SS; + oldsp = oldsp2 = ESP; + cpl_override = 1; + if (tr.access & 8) { + addr = 4 + tr.base + (DPL << 3); + newss = readmemw(0, addr + 4); + if (cpu_16bitbus) { + newsp = readmemw(0, addr); + newsp |= (readmemw(0, addr + 2) << 16); + } else + newsp = readmeml(0, addr); + } else { + addr = 2 + tr.base + (DPL * 4); + newss = readmemw(0, addr + 2); + newsp = readmemw(0, addr); + } + cpl_override = 0; + if (cpu_state.abrt) + return; + x86seg_log("New stack %04X:%08X\n", newss, newsp); + if (!(newss & 0xfffc)) { + x86ts(NULL, newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit); + x86ts(NULL, newss & ~3); + return; + } + addr += dt->base; + x86seg_log("Read stack seg\n"); + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + x86seg_log("Read stack seg done!\n"); + if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) { + x86ts(NULL, newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + x86ts("Call gate loading SS unknown type", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + x86ss("Call gate loading SS not present", newss & 0xfffc); + return; + } + if (!stack32) + oldsp &= 0xffff; + SS = newss; + set_stack32((segdat2[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + do_seg_load(&cpu_state.seg_ss, segdat2); - x86seg_log("Set access 1\n"); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + x86seg_log("Set access 1\n"); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); - cpu_state.pc = newpc; + set_use32(segdat[3] & 0x0040); + cpu_state.pc = newpc; - x86seg_log("Set access 2\n"); + x86seg_log("Set access 2\n"); - cpl_override = 1; - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - x86seg_log("Type %04X\n", type); - if (type == 0x0c00) { - PUSHL(oldss); - PUSHL(oldsp2); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + x86seg_log("Type %04X\n", type); + if (type == 0x0c00) { + PUSHL(oldss); + PUSHL(oldsp2); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - if (count) { - while (count--) { - PUSHL(readmeml(oldssbase, oldsp + (count << 2))); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + return; + } + if (count) { + while (count--) { + PUSHL(readmeml(oldssbase, oldsp + (count << 2))); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - } - } - } else { - x86seg_log("Stack %04X\n", SP); - PUSHW(oldss); - x86seg_log("Write SS to %04X:%04X\n", SS, SP); - PUSHW(oldsp2); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + return; + } + } + } + } else { + x86seg_log("Stack %04X\n", SP); + PUSHW(oldss); + x86seg_log("Write SS to %04X:%04X\n", SS, SP); + PUSHW(oldsp2); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - x86seg_log("Write SP to %04X:%04X\n", SS, SP); - if (count) { - while (count--) { - tempw = readmemw(oldssbase, (oldsp & 0xffff) + (count << 1)); - x86seg_log("PUSH %04X\n", tempw); - PUSHW(tempw); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + return; + } + x86seg_log("Write SP to %04X:%04X\n", SS, SP); + if (count) { + while (count--) { + tempw = readmemw(oldssbase, (oldsp & 0xffff) + (count << 1)); + x86seg_log("PUSH %04X\n", tempw); + PUSHW(tempw); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - } - } - } - cycles -= timing_call_pm_gate_inner; - break; - } else if (DPL > CPL) { - x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL",seg2 & 0xfffc); - return; - } - /*FALLTHROUGH*/ - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + return; + } + } + } + } + cycles -= timing_call_pm_gate_inner; + break; + } else if (DPL > CPL) { + x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL", seg2 & 0xfffc); + return; + } + /*FALLTHROUGH*/ + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); - cpu_state.pc = newpc; + set_use32(segdat[3] & 0x0040); + cpu_state.pc = newpc; - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - cycles -= timing_call_pm_gate; - break; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + cycles -= timing_call_pm_gate; + break; - default: - x86gpf("loadcscall(): Unknown subtype", seg2 & 0xfffc); - return; - } - break; + default: + x86gpf("loadcscall(): Unknown subtype", seg2 & 0xfffc); + return; + } + break; - case 0x0100: /* 286 Task gate */ - case 0x0900: /* 386 Task gate */ + case 0x0100: /* 286 Task gate */ + case 0x0900: /* 386 Task gate */ #ifdef USE_NEW_DYNAREC - cpu_state.pc = old_pc; + cpu_state.pc = old_pc; #else - cpu_state.pc = oxpc; + cpu_state.pc = oxpc; #endif - cpl_override = 1; - taskswitch286(seg, segdat, segdat[2] & 0x0800); - cpl_override = 0; - break; + cpl_override = 1; + taskswitch286(seg, segdat, segdat[2] & 0x0800); + cpl_override = 0; + break; - default: - x86gpf("loadcscall(): Unknown type", seg & 0xfffc); - return; - } - } + default: + x86gpf("loadcscall(): Unknown type", seg & 0xfffc); + return; + } + } } else { - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.seg = seg; - cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.seg = seg; + cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif } } - void pmoderetf(int is32, uint16_t off) { - uint16_t segdat[4], segdat2[4], seg,newss; - uint32_t newpc, newsp, addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t segdat[4], segdat2[4], seg, newss; + uint32_t newpc, newsp, addr, oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + x86seg *dt; x86seg_log("RETF %i %04X:%04X %08X %04X\n", is32, CS, cpu_state.pc, cr0, cpu_state.eflags); if (is32) { - newpc = POPL(); - seg = POPL(); + newpc = POPL(); + seg = POPL(); } else { - x86seg_log("PC read from %04X:%04X\n", SS, SP); - newpc = POPW(); - x86seg_log("CS read from %04X:%04X\n", SS, SP); - seg = POPW(); + x86seg_log("PC read from %04X:%04X\n", SS, SP); + newpc = POPW(); + x86seg_log("CS read from %04X:%04X\n", SS, SP); + seg = POPW(); } if (cpu_state.abrt) - return; + return; x86seg_log("Return to %04X:%08X\n", seg, newpc); if ((seg & 0x0003) < CPL) { - ESP = oldsp; - x86gpf("pmoderetf(): seg < CPL", seg & 0xfffc); - return; + ESP = oldsp; + x86gpf("pmoderetf(): seg < CPL", seg & 0xfffc); + return; } if (!(seg & 0xfffc)) { - x86gpf("pmoderetf(): seg is NULL", 0); - return; + x86gpf("pmoderetf(): seg is NULL", 0); + return; } addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; + dt = (seg & 0x0004) ? &ldt : &gdt; if ((addr + 7) > dt->limit) { - x86gpf("pmoderetf(): Selector > DT limit", seg & 0xfffc); - return; + x86gpf("pmoderetf(): Selector > DT limit", seg & 0xfffc); + return; } addr += dt->base; read_descriptor(addr, segdat, segdat32, 1); if (cpu_state.abrt) { - ESP = oldsp; - return; + ESP = oldsp; + return; } oaddr = addr; x86seg_log("CPL %i RPL %i %i\n", CPL, seg & 0x0003, is32); if (stack32) - ESP += off; + ESP += off; else - SP += off; + SP += off; if (CPL == (seg & 0x0003)) { - x86seg_log("RETF CPL = RPL %04X\n", segdat[2]); - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if (CPL != DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Non-conforming CPL != DPL", seg & 0xfffc); - return; - } - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if (CPL < DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Conforming CPL < DPL", seg & 0xfffc); - return; - } - break; - default: - x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - ESP = oldsp; - x86np("RETF CS not present", seg & 0xfffc); - return; - } + x86seg_log("RETF CPL = RPL %04X\n", segdat[2]); + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if (CPL != DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Non-conforming CPL != DPL", seg & 0xfffc); + return; + } + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if (CPL < DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Conforming CPL < DPL", seg & 0xfffc); + return; + } + break; + default: + x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + ESP = oldsp; + x86np("RETF CS not present", seg & 0xfffc); + return; + } - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - cpu_state.pc = newpc; - if (segdat[2] & 0x0400) - segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.pc = newpc; + if (segdat[2] & 0x0400) + segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); + set_use32(segdat[3] & 0x0040); - cycles -= timing_retf_pm; + cycles -= timing_retf_pm; } else { - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if ((seg & 0x0003) != DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Non-conforming RPL != DPL", seg & 0xfffc); - return; - } - x86seg_log("RETF non-conforming, %i %i\n", seg & 0x0003, DPL); - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if ((seg & 0x0003) < DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Conforming RPL < DPL", seg & 0xfffc); - return; - } - x86seg_log("RETF conforming, %i %i\n", seg & 0x0003, DPL); - break; - default: - ESP = oldsp; - x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - ESP = oldsp; - x86np("RETF CS not present", seg & 0xfffc); - return; - } - if (is32) { - newsp = POPL(); - newss = POPL(); - if (cpu_state.abrt) - return; - } else { - x86seg_log("SP read from %04X:%04X\n", SS, SP); - newsp = POPW(); - x86seg_log("SS read from %04X:%04X\n", SS, SP); - newss = POPW(); - if (cpu_state.abrt) - return; - } - x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); - if (!(newss & 0xfffc)) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS selector is zero",newss&~3); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS selector > DT limit", newss & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); - if ((newss & 0x0003) != (seg & 0x0003)) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS RPL > CS RPL", newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS unknown type", newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - ESP = oldsp; - x86np("RETF loading SS not present", newss & 0xfffc); - return; - } - if (DPL2 != (seg & 3)) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS DPL != CS RPL",newss & 0xfffc); - return; - } - SS = newss; - set_stack32((segdat2[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if ((seg & 0x0003) != DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Non-conforming RPL != DPL", seg & 0xfffc); + return; + } + x86seg_log("RETF non-conforming, %i %i\n", seg & 0x0003, DPL); + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if ((seg & 0x0003) < DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Conforming RPL < DPL", seg & 0xfffc); + return; + } + x86seg_log("RETF conforming, %i %i\n", seg & 0x0003, DPL); + break; + default: + ESP = oldsp; + x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + ESP = oldsp; + x86np("RETF CS not present", seg & 0xfffc); + return; + } + if (is32) { + newsp = POPL(); + newss = POPL(); + if (cpu_state.abrt) + return; + } else { + x86seg_log("SP read from %04X:%04X\n", SS, SP); + newsp = POPW(); + x86seg_log("SS read from %04X:%04X\n", SS, SP); + newss = POPW(); + if (cpu_state.abrt) + return; + } + x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); + if (!(newss & 0xfffc)) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS selector is zero", newss & ~3); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS selector > DT limit", newss & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); + if ((newss & 0x0003) != (seg & 0x0003)) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS RPL > CS RPL", newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS unknown type", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + ESP = oldsp; + x86np("RETF loading SS not present", newss & 0xfffc); + return; + } + if (DPL2 != (seg & 3)) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS DPL != CS RPL", newss & 0xfffc); + return; + } + SS = newss; + set_stack32((segdat2[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; + do_seg_load(&cpu_state.seg_ss, segdat2); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - /* Conforming segments don't change CPL, so CPL = RPL */ - if (segdat[2] & 0x0400) - segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); - cpu_state.pc = newpc; - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + /* Conforming segments don't change CPL, so CPL = RPL */ + if (segdat[2] & 0x0400) + segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); + cpu_state.pc = newpc; + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); + set_use32(segdat[3] & 0x0040); - if (stack32) - ESP += off; - else - SP += off; + if (stack32) + ESP += off; + else + SP += off; - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); - cycles -= timing_retf_pm_outer; + check_seg_valid(&cpu_state.seg_ds); + check_seg_valid(&cpu_state.seg_es); + check_seg_valid(&cpu_state.seg_fs); + check_seg_valid(&cpu_state.seg_gs); + cycles -= timing_retf_pm_outer; } } - void pmodeint(int num, int soft) { - uint16_t segdat[4], segdat2[4]; - uint16_t segdat3[4]; - uint16_t newss, seg = 0; - int type, new_cpl; - uint32_t addr, oaddr; - uint32_t oldss, oldsp; - uint32_t newsp; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t segdat[4], segdat2[4]; + uint16_t segdat3[4]; + uint16_t newss, seg = 0; + int type, new_cpl; + uint32_t addr, oaddr; + uint32_t oldss, oldsp; + uint32_t newsp; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; uint32_t *segdat332 = (uint32_t *) segdat3; - x86seg *dt; + x86seg *dt; if ((cpu_state.eflags & VM_FLAG) && (IOPL != 3) && soft) { - x86seg_log("V86 banned int\n"); - x86gpf("pmodeint(): V86 banned int", 0); - return; + x86seg_log("V86 banned int\n"); + x86gpf("pmodeint(): V86 banned int", 0); + return; } addr = (num << 3); if ((addr + 7) > idt.limit) { - if (num == 0x08) { - /* Triple fault - reset! */ - softresetx86(); - cpu_set_edx(); - } else if (num == 0x0d) - pmodeint(8, 0); - else - x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft); - x86seg_log("addr >= IDT.limit\n"); - return; + if (num == 0x08) { + /* Triple fault - reset! */ + softresetx86(); + cpu_set_edx(); + } else if (num == 0x0d) + pmodeint(8, 0); + else + x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft); + x86seg_log("addr >= IDT.limit\n"); + return; } addr += idt.base; read_descriptor(addr, segdat, segdat32, 1); if (cpu_state.abrt) { - x86seg_log("Abrt reading from %08X\n", addr); - return; + x86seg_log("Abrt reading from %08X\n", addr); + return; } oaddr = addr; x86seg_log("Addr %08X seg %04X %04X %04X %04X\n", addr, segdat[0], segdat[1], segdat[2], segdat[3]); if (!(segdat[2] & 0x1f00)) { - /* This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn */ - if (cpu_state.eflags & VM_FLAG) - x86gpf_expected("pmodeint(): Expected vector descriptor with bad type", (num << 3) + 2); - else - x86gpf("pmodeint(): Vector descriptor with bad type", (num << 3) + 2); - return; + /* This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn */ + if (cpu_state.eflags & VM_FLAG) + x86gpf_expected("pmodeint(): Expected vector descriptor with bad type", (num << 3) + 2); + else + x86gpf("pmodeint(): Vector descriptor with bad type", (num << 3) + 2); + return; } if ((DPL < CPL) && soft) { - x86gpf("pmodeint(): Vector DPL < CPL", (num << 3) + 2); - return; + x86gpf("pmodeint(): Vector DPL < CPL", (num << 3) + 2); + return; } type = segdat[2] & 0x1f00; if (((type == 0x0e00) || (type == 0x0f00)) && !is386) { - x86gpf("pmodeint(): Gate type illegal on 286", seg & 0xfffc); - return; + x86gpf("pmodeint(): Gate type illegal on 286", seg & 0xfffc); + return; } switch (type) { - case 0x0600: case 0x0700: case 0x0e00: case 0x0f00: /* Interrupt and trap gates */ - intgatesize = (type >= 0x0800) ? 32 : 16; - if (!(segdat[2] & 0x8000)) { - x86np("Int gate not present", (num << 3) | 2); - return; - } - seg = segdat[1]; - new_cpl = seg & 0x0003; + case 0x0600: + case 0x0700: + case 0x0e00: + case 0x0f00: /* Interrupt and trap gates */ + intgatesize = (type >= 0x0800) ? 32 : 16; + if (!(segdat[2] & 0x8000)) { + x86np("Int gate not present", (num << 3) | 2); + return; + } + seg = segdat[1]; + new_cpl = seg & 0x0003; - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("pmodeint(): Interrupt or trap gate selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - oaddr = addr; + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("pmodeint(): Interrupt or trap gate selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + oaddr = addr; - if (DPL2 > CPL) { - x86gpf("pmodeint(): Interrupt or trap gate DPL > CPL", seg & 0xfffc); - return; - } - switch (segdat2[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if (DPL2 < CPL) { - if (!(segdat2[2] & 0x8000)) { - x86np("Int gate CS not present", segdat[1] & 0xfffc); - return; - } - if ((cpu_state.eflags & VM_FLAG) && DPL2) { - x86gpf("pmodeint(): Interrupt or trap gate non-zero DPL in V86 mode", segdat[1] & 0xfffc); - return; - } - /* Load new stack */ - oldss = SS; - oldsp = ESP; - cpl_override = 1; - if (tr.access & 8) { - addr = 4 + tr.base + (DPL2 << 3); - newss = readmemw(0, addr + 4); - newsp = readmeml(0, addr); - } else { - addr = 2 + tr.base + (DPL2 << 2); - newss = readmemw(0, addr + 2); - newsp = readmemw(0, addr); - } - cpl_override = 0; - if (!(newss & 0xfffc)) { - x86ss("pmodeint(): Interrupt or trap gate stack segment is NULL", newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86ss("pmodeint(): Interrupt or trap gate stack segment > DT", newss & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat3, segdat332, 1); - if (cpu_state.abrt) - return; - if ((newss & 3) != DPL2) { - x86ss("pmodeint(): Interrupt or trap gate tack segment RPL > DPL",newss & 0xfffc); - return; - } - if (DPL3 != DPL2) { - x86ss("pmodeint(): Interrupt or trap gate tack segment DPL > DPL",newss & 0xfffc); - return; - } - if ((segdat3[2] & 0x1a00) != 0x1200) { - x86ss("pmodeint(): Interrupt or trap gate stack segment bad type", newss & 0xfffc); - return; - } - if (!(segdat3[2] & 0x8000)) { - x86np("Int gate loading SS not present", newss & 0xfffc); - return; - } - SS = newss; - set_stack32((segdat3[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat3); + if (DPL2 > CPL) { + x86gpf("pmodeint(): Interrupt or trap gate DPL > CPL", seg & 0xfffc); + return; + } + switch (segdat2[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if (DPL2 < CPL) { + if (!(segdat2[2] & 0x8000)) { + x86np("Int gate CS not present", segdat[1] & 0xfffc); + return; + } + if ((cpu_state.eflags & VM_FLAG) && DPL2) { + x86gpf("pmodeint(): Interrupt or trap gate non-zero DPL in V86 mode", segdat[1] & 0xfffc); + return; + } + /* Load new stack */ + oldss = SS; + oldsp = ESP; + cpl_override = 1; + if (tr.access & 8) { + addr = 4 + tr.base + (DPL2 << 3); + newss = readmemw(0, addr + 4); + newsp = readmeml(0, addr); + } else { + addr = 2 + tr.base + (DPL2 << 2); + newss = readmemw(0, addr + 2); + newsp = readmemw(0, addr); + } + cpl_override = 0; + if (!(newss & 0xfffc)) { + x86ss("pmodeint(): Interrupt or trap gate stack segment is NULL", newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86ss("pmodeint(): Interrupt or trap gate stack segment > DT", newss & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat3, segdat332, 1); + if (cpu_state.abrt) + return; + if ((newss & 3) != DPL2) { + x86ss("pmodeint(): Interrupt or trap gate tack segment RPL > DPL", newss & 0xfffc); + return; + } + if (DPL3 != DPL2) { + x86ss("pmodeint(): Interrupt or trap gate tack segment DPL > DPL", newss & 0xfffc); + return; + } + if ((segdat3[2] & 0x1a00) != 0x1200) { + x86ss("pmodeint(): Interrupt or trap gate stack segment bad type", newss & 0xfffc); + return; + } + if (!(segdat3[2] & 0x8000)) { + x86np("Int gate loading SS not present", newss & 0xfffc); + return; + } + SS = newss; + set_stack32((segdat3[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; + do_seg_load(&cpu_state.seg_ss, segdat3); - cpl_override = 1; - writememw(0, addr + 4, segdat3[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat3[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - x86seg_log("New stack %04X:%08X\n", SS, ESP); - cpl_override = 1; - if (type >= 0x0800) { - if (cpu_state.eflags & VM_FLAG) { - PUSHL(GS); - PUSHL(FS); - PUSHL(DS); - PUSHL(ES); - if (cpu_state.abrt) - return; - loadseg(0, &cpu_state.seg_ds); - loadseg(0, &cpu_state.seg_es); - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); - } - PUSHL(oldss); - PUSHL(oldsp); - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); - PUSHL(cpu_state.pc); - if (cpu_state.abrt) - return; - } else { - PUSHW(oldss); - PUSHW(oldsp); - PUSHW(cpu_state.flags); - PUSHW(CS); - PUSHW(cpu_state.pc); - if (cpu_state.abrt) - return; - } - cpl_override = 0; - cpu_state.seg_cs.access = 0x80; - cycles -= timing_int_pm_outer - timing_int_pm; - break; - } else if (DPL2 != CPL) { - x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc); - return; - } - /*FALLTHROUGH*/ - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if (!(segdat2[2] & 0x8000)) { - x86np("Int gate CS not present", segdat[1] & 0xfffc); - return; - } - if ((cpu_state.eflags & VM_FLAG) && (DPL2 < CPL)) { - x86gpf("pmodeint(): DPL < CPL in V86 mode", seg &~ 0xfffc); - return; - } - if (type > 0x0800) { - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); - PUSHL(cpu_state.pc); - if (cpu_state.abrt) - return; - } else { - PUSHW(cpu_state.flags); - PUSHW(CS); - PUSHW(cpu_state.pc); - if (cpu_state.abrt) - return; - } - new_cpl = CS & 3; - break; - default: - x86gpf("pmodeint(): Unknown type", seg & 0xfffc); - return; - } - do_seg_load(&cpu_state.seg_cs, segdat2); - CS = (seg & 0xfffc) | new_cpl; - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (new_cpl << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + x86seg_log("New stack %04X:%08X\n", SS, ESP); + cpl_override = 1; + if (type >= 0x0800) { + if (cpu_state.eflags & VM_FLAG) { + PUSHL(GS); + PUSHL(FS); + PUSHL(DS); + PUSHL(ES); + if (cpu_state.abrt) + return; + loadseg(0, &cpu_state.seg_ds); + loadseg(0, &cpu_state.seg_es); + loadseg(0, &cpu_state.seg_fs); + loadseg(0, &cpu_state.seg_gs); + } + PUSHL(oldss); + PUSHL(oldsp); + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); + PUSHL(CS); + PUSHL(cpu_state.pc); + if (cpu_state.abrt) + return; + } else { + PUSHW(oldss); + PUSHW(oldsp); + PUSHW(cpu_state.flags); + PUSHW(CS); + PUSHW(cpu_state.pc); + if (cpu_state.abrt) + return; + } + cpl_override = 0; + cpu_state.seg_cs.access = 0x80; + cycles -= timing_int_pm_outer - timing_int_pm; + break; + } else if (DPL2 != CPL) { + x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc); + return; + } + /*FALLTHROUGH*/ + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if (!(segdat2[2] & 0x8000)) { + x86np("Int gate CS not present", segdat[1] & 0xfffc); + return; + } + if ((cpu_state.eflags & VM_FLAG) && (DPL2 < CPL)) { + x86gpf("pmodeint(): DPL < CPL in V86 mode", seg & ~0xfffc); + return; + } + if (type > 0x0800) { + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); + PUSHL(CS); + PUSHL(cpu_state.pc); + if (cpu_state.abrt) + return; + } else { + PUSHW(cpu_state.flags); + PUSHW(CS); + PUSHW(cpu_state.pc); + if (cpu_state.abrt) + return; + } + new_cpl = CS & 3; + break; + default: + x86gpf("pmodeint(): Unknown type", seg & 0xfffc); + return; + } + do_seg_load(&cpu_state.seg_cs, segdat2); + CS = (seg & 0xfffc) | new_cpl; + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (new_cpl << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - if (type > 0x0800) - cpu_state.pc = segdat[0] | (segdat[3] << 16); - else - cpu_state.pc = segdat[0]; - set_use32(segdat2[3] & 0x40); + if (type > 0x0800) + cpu_state.pc = segdat[0] | (segdat[3] << 16); + else + cpu_state.pc = segdat[0]; + set_use32(segdat2[3] & 0x40); - cpl_override = 1; - writememw(0, oaddr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, oaddr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - cpu_state.eflags &= ~VM_FLAG; - cpu_cur_status &= ~CPU_STATUS_V86; - if (!(type & 0x100)) - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~(T_FLAG | NT_FLAG); - cycles -= timing_int_pm; - break; + cpu_state.eflags &= ~VM_FLAG; + cpu_cur_status &= ~CPU_STATUS_V86; + if (!(type & 0x100)) + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~(T_FLAG | NT_FLAG); + cycles -= timing_int_pm; + break; - case 0x500: /* Task gate */ - seg = segdat[1]; - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("pmodeint(): Task gate selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - if (!(segdat2[2] & 0x8000)) { - x86np("Int task gate not present", segdat[1] & 0xfffc); - return; - } - optype = OPTYPE_INT; - cpl_override = 1; - taskswitch286(seg, segdat2, segdat2[2] & 0x0800); - cpl_override = 0; - break; + case 0x500: /* Task gate */ + seg = segdat[1]; + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("pmodeint(): Task gate selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + if (!(segdat2[2] & 0x8000)) { + x86np("Int task gate not present", segdat[1] & 0xfffc); + return; + } + optype = OPTYPE_INT; + cpl_override = 1; + taskswitch286(seg, segdat2, segdat2[2] & 0x0800); + cpl_override = 0; + break; - default: - x86gpf("Protected mode interrupt unknown type", seg & 0xfffc); - return; + default: + x86gpf("Protected mode interrupt unknown type", seg & 0xfffc); + return; } } - void pmodeiret(int is32) { - uint16_t newss, seg = 0; - uint16_t segdat[4],segdat2[4]; - uint16_t segs[4]; - uint32_t tempflags, flagmask; - uint32_t newpc, newsp; - uint32_t addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t newss, seg = 0; + uint16_t segdat[4], segdat2[4]; + uint16_t segs[4]; + uint32_t tempflags, flagmask; + uint32_t newpc, newsp; + uint32_t addr, oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + x86seg *dt; if (is386 && (cpu_state.eflags & VM_FLAG)) { - if (IOPL != 3) { - x86gpf("Protected mode IRET: IOPL != 3", 0); - return; - } + if (IOPL != 3) { + x86gpf("Protected mode IRET: IOPL != 3", 0); + return; + } #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - if (is32) { - newpc = POPL(); - seg = POPL(); - tempflags = POPL(); - } else { - newpc = POPW(); - seg = POPW(); - tempflags = POPW(); - } - if (cpu_state.abrt) - return; + if (is32) { + newpc = POPL(); + seg = POPL(); + tempflags = POPL(); + } else { + newpc = POPW(); + seg = POPW(); + tempflags = POPW(); + } + if (cpu_state.abrt) + return; - cpu_state.pc = newpc; - cpu_state.seg_cs.base= seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.access |= 0x80; - cpu_state.seg_cs.ar_high = 0x10; - CS = seg; - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xcfd5) | 2; - cycles -= timing_iret_rm; - return; + cpu_state.pc = newpc; + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.access |= 0x80; + cpu_state.seg_cs.ar_high = 0x10; + CS = seg; + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xcfd5) | 2; + cycles -= timing_iret_rm; + return; } if (cpu_state.flags & NT_FLAG) { - seg = readmemw(tr.base, 0); - addr = seg & 0xfff8; - if (seg & 0x0004) { - x86seg_log("TS LDT %04X %04X IRET\n", seg, gdt.limit); - x86ts("pmodeiret(): Selector points to LDT", seg & 0xfffc); - return; - } else { - if ((addr + 7) > gdt.limit) { - x86ts(NULL,seg & 0xfffc); - return; - } - addr += gdt.base; - } - cpl_override = 1; - read_descriptor(addr, segdat, segdat32, 1); - taskswitch286(seg, segdat,segdat[2] & 0x0800); - cpl_override = 0; - return; + seg = readmemw(tr.base, 0); + addr = seg & 0xfff8; + if (seg & 0x0004) { + x86seg_log("TS LDT %04X %04X IRET\n", seg, gdt.limit); + x86ts("pmodeiret(): Selector points to LDT", seg & 0xfffc); + return; + } else { + if ((addr + 7) > gdt.limit) { + x86ts(NULL, seg & 0xfffc); + return; + } + addr += gdt.base; + } + cpl_override = 1; + read_descriptor(addr, segdat, segdat32, 1); + taskswitch286(seg, segdat, segdat[2] & 0x0800); + cpl_override = 0; + return; } #ifndef USE_NEW_DYNAREC - oxpc=cpu_state.pc; + oxpc = cpu_state.pc; #endif flagmask = 0xffff; if (CPL != 0) - flagmask &= ~0x3000; + flagmask &= ~0x3000; if (IOPL < CPL) - flagmask &= ~0x200; + flagmask &= ~0x200; if (is32) { - newpc = POPL(); - seg = POPL(); - tempflags = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - if (is386 && ((tempflags >> 16) & VM_FLAG)) { - newsp = POPL(); - newss = POPL(); - segs[0] = POPL(); - segs[1] = POPL(); - segs[2] = POPL(); - segs[3] = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - cpu_state.eflags = tempflags >> 16; - cpu_cur_status |= CPU_STATUS_V86; - loadseg(segs[0], &cpu_state.seg_es); - do_seg_v86_init(&cpu_state.seg_es); - loadseg(segs[1], &cpu_state.seg_ds); - do_seg_v86_init(&cpu_state.seg_ds); - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - loadseg(segs[2], &cpu_state.seg_fs); - do_seg_v86_init(&cpu_state.seg_fs); - loadseg(segs[3], &cpu_state.seg_gs); - do_seg_v86_init(&cpu_state.seg_gs); + newpc = POPL(); + seg = POPL(); + tempflags = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + if (is386 && ((tempflags >> 16) & VM_FLAG)) { + newsp = POPL(); + newss = POPL(); + segs[0] = POPL(); + segs[1] = POPL(); + segs[2] = POPL(); + segs[3] = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + cpu_state.eflags = tempflags >> 16; + cpu_cur_status |= CPU_STATUS_V86; + loadseg(segs[0], &cpu_state.seg_es); + do_seg_v86_init(&cpu_state.seg_es); + loadseg(segs[1], &cpu_state.seg_ds); + do_seg_v86_init(&cpu_state.seg_ds); + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + loadseg(segs[2], &cpu_state.seg_fs); + do_seg_v86_init(&cpu_state.seg_fs); + loadseg(segs[3], &cpu_state.seg_gs); + do_seg_v86_init(&cpu_state.seg_gs); - cpu_state.pc = newpc & 0xffff; - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS = seg; - cpu_state.seg_cs.access = 0xe2; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.pc = newpc & 0xffff; + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + CS = seg; + cpu_state.seg_cs.access = 0xe2; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - ESP = newsp; - loadseg(newss, &cpu_state.seg_ss); - do_seg_v86_init(&cpu_state.seg_ss); - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - use32 = 0; - cpu_cur_status &= ~CPU_STATUS_USE32; - cpu_state.flags = (tempflags & 0xffd5) | 2; - cycles -= timing_iret_v86; - return; - } + ESP = newsp; + loadseg(newss, &cpu_state.seg_ss); + do_seg_v86_init(&cpu_state.seg_ss); + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + use32 = 0; + cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_state.flags = (tempflags & 0xffd5) | 2; + cycles -= timing_iret_v86; + return; + } } else { - newpc = POPW(); - seg = POPW(); - tempflags = POPW(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } + newpc = POPW(); + seg = POPW(); + tempflags = POPW(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } } if (!(seg & 0xfffc)) { - ESP = oldsp; - x86gpf("pmodeiret(): Selector is NULL", 0); - return; + ESP = oldsp; + x86gpf("pmodeiret(): Selector is NULL", 0); + return; } addr = seg & 0xfff8; - dt = (seg & 0x0004) ? & ldt : &gdt; + dt = (seg & 0x0004) ? &ldt : &gdt; if ((addr + 7) > dt->limit) { - ESP = oldsp; - x86gpf("pmodeiret(): Selector > DT limit", seg & 0xfffc); - return; + ESP = oldsp; + x86gpf("pmodeiret(): Selector > DT limit", seg & 0xfffc); + return; } addr += dt->base; if ((seg & 0x0003) < CPL) { - ESP = oldsp; - x86gpf("pmodeiret(): RPL < CPL", seg & 0xfffc); - return; + ESP = oldsp; + x86gpf("pmodeiret(): RPL < CPL", seg & 0xfffc); + return; } read_descriptor(addr, segdat, segdat32, 1); if (cpu_state.abrt) { - ESP = oldsp; - return; + ESP = oldsp; + return; } switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if ((seg & 0x0003) != DPL) { - ESP = oldsp; - x86gpf("pmodeiret(): Non-conforming RPL != DPL", seg & 0xfffc); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /* Conforming code */ - if ((seg & 0x0003) < DPL) { - ESP = oldsp; - x86gpf("pmodeiret(): Conforming RPL < DPL",seg&~3); - return; - } - break; - default: - ESP = oldsp; - x86gpf("pmodeiret(): Unknown type", seg & 0xfffc); - return; + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming code */ + if ((seg & 0x0003) != DPL) { + ESP = oldsp; + x86gpf("pmodeiret(): Non-conforming RPL != DPL", seg & 0xfffc); + return; + } + break; + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /* Conforming code */ + if ((seg & 0x0003) < DPL) { + ESP = oldsp; + x86gpf("pmodeiret(): Conforming RPL < DPL", seg & ~3); + return; + } + break; + default: + ESP = oldsp; + x86gpf("pmodeiret(): Unknown type", seg & 0xfffc); + return; } if (!(segdat[2] & 0x8000)) { - ESP = oldsp; - x86np("IRET CS not present", seg & 0xfffc); - return; + ESP = oldsp; + x86np("IRET CS not present", seg & 0xfffc); + return; } if ((seg & 0x0003) == CPL) { - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 0x0003) << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 0x0003) << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); + set_use32(segdat[3] & 0x0040); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - cycles -= timing_iret_pm; - } else { /* Return to outer level */ - oaddr = addr; - x86seg_log("Outer level\n"); - if (is32) { - newsp = POPL(); - newss = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - } else { - newsp = POPW(); - newss = POPW(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - } + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + cycles -= timing_iret_pm; + } else { /* Return to outer level */ + oaddr = addr; + x86seg_log("Outer level\n"); + if (is32) { + newsp = POPL(); + newss = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + } else { + newsp = POPW(); + newss = POPW(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + } - x86seg_log("IRET load stack %04X:%04X\n", newss, newsp); + x86seg_log("IRET load stack %04X:%04X\n", newss, newsp); - if (!(newss & 0xfffc)) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS selector is zero", newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS selector > DT limit", newss & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - if ((newss & 3) != (seg & 3)) { - SP = oldsp; - x86gpf("pmodeiret(): New SS RPL > CS RPL",newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS bad type", newss & 0xfffc); - return; - } - if (DPL2 != (seg & 0x0003)) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS DPL != CS RPL",newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - ESP = oldsp; - x86np("IRET loading SS not present", newss & 0xfffc); - return; - } - SS = newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + if (!(newss & 0xfffc)) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS selector is zero", newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS selector > DT limit", newss & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + if ((newss & 3) != (seg & 3)) { + SP = oldsp; + x86gpf("pmodeiret(): New SS RPL > CS RPL", newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS bad type", newss & 0xfffc); + return; + } + if (DPL2 != (seg & 0x0003)) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS DPL != CS RPL", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + ESP = oldsp; + x86np("IRET loading SS not present", newss & 0xfffc); + return; + } + SS = newss; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; + do_seg_load(&cpu_state.seg_ss, segdat2); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - /* Conforming segments don't change CPL, so CPL = RPL */ - if (segdat[2] & 0x0400) - segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + /* Conforming segments don't change CPL, so CPL = RPL */ + if (segdat[2] & 0x0400) + segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 3) << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 3) << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x40); + set_use32(segdat[3] & 0x40); - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); - cycles -= timing_iret_pm_outer; + check_seg_valid(&cpu_state.seg_ds); + check_seg_valid(&cpu_state.seg_es); + check_seg_valid(&cpu_state.seg_fs); + check_seg_valid(&cpu_state.seg_gs); + cycles -= timing_iret_pm_outer; } - cpu_state.pc = newpc; - cpu_state.flags = (cpu_state.flags &~ flagmask) | (tempflags & flagmask & 0xffd5) | 2; + cpu_state.pc = newpc; + cpu_state.flags = (cpu_state.flags & ~flagmask) | (tempflags & flagmask & 0xffd5) | 2; if (is32) - cpu_state.eflags = tempflags >> 16; + cpu_state.eflags = tempflags >> 16; } - void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { - uint16_t tempw, new_ldt; - uint16_t new_es, new_cs, new_ss, new_ds, new_fs, new_gs; - uint16_t segdat2[4]; - uint32_t base, limit; - uint32_t templ, new_cr3 = 0; - uint32_t new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp; - uint32_t new_esi, new_edi, new_pc, new_flags, addr; + uint16_t tempw, new_ldt; + uint16_t new_es, new_cs, new_ss, new_ds, new_fs, new_gs; + uint16_t segdat2[4]; + uint32_t base, limit; + uint32_t templ, new_cr3 = 0; + uint32_t new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp; + uint32_t new_esi, new_edi, new_pc, new_flags, addr; uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + x86seg *dt; - base = segdat[1] | ((segdat[2] & 0x00ff) << 16); + base = segdat[1] | ((segdat[2] & 0x00ff) << 16); limit = segdat[0]; if (is386) { - base |= (segdat[3] >> 8) << 24; - limit |= (segdat[3] & 0x000f) << 16; + base |= (segdat[3] >> 8) << 24; + limit |= (segdat[3] & 0x000f) << 16; } if (is32) { - if (limit < 103) { - x86ts("taskswitch286(): limit < 103", seg); - return; - } + if (limit < 103) { + x86ts("taskswitch286(): limit < 103", seg); + return; + } - if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw |= 0x0200; - if (tr.seg & 0x0004) - writememw(ldt.base, (seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw |= 0x0200; + if (tr.seg & 0x0004) + writememw(ldt.base, (seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if (optype == IRET) - cpu_state.flags &= ~NT_FLAG; + if (optype == IRET) + cpu_state.flags &= ~NT_FLAG; - cpu_386_flags_rebuild(); - writememl(tr.base, 0x1C, cr3); - writememl(tr.base, 0x20, cpu_state.pc); - writememl(tr.base, 0x24, cpu_state.flags | (cpu_state.eflags << 16)); + cpu_386_flags_rebuild(); + writememl(tr.base, 0x1C, cr3); + writememl(tr.base, 0x20, cpu_state.pc); + writememl(tr.base, 0x24, cpu_state.flags | (cpu_state.eflags << 16)); - writememl(tr.base, 0x28, EAX); - writememl(tr.base, 0x2C, ECX); - writememl(tr.base, 0x30, EDX); - writememl(tr.base, 0x34, EBX); - writememl(tr.base, 0x38, ESP); - writememl(tr.base, 0x3C, EBP); - writememl(tr.base, 0x40, ESI); - writememl(tr.base, 0x44, EDI); + writememl(tr.base, 0x28, EAX); + writememl(tr.base, 0x2C, ECX); + writememl(tr.base, 0x30, EDX); + writememl(tr.base, 0x34, EBX); + writememl(tr.base, 0x38, ESP); + writememl(tr.base, 0x3C, EBP); + writememl(tr.base, 0x40, ESI); + writememl(tr.base, 0x44, EDI); - writememl(tr.base, 0x48, ES); - writememl(tr.base, 0x4C, CS); - writememl(tr.base, 0x50, SS); - writememl(tr.base, 0x54, DS); - writememl(tr.base, 0x58, FS); - writememl(tr.base, 0x5C, GS); + writememl(tr.base, 0x48, ES); + writememl(tr.base, 0x4C, CS); + writememl(tr.base, 0x50, SS); + writememl(tr.base, 0x54, DS); + writememl(tr.base, 0x58, FS); + writememl(tr.base, 0x5C, GS); - if ((optype == JMP) || (optype == IRET)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw &= ~0x0200; - if (tr.seg & 0x0004) - writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == IRET)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw &= ~0x0200; + if (tr.seg & 0x0004) + writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if ((optype == OPTYPE_INT) || (optype == CALL)) { - writememl(base, 0, tr.seg); - if (cpu_state.abrt) - return; - } + if ((optype == OPTYPE_INT) || (optype == CALL)) { + writememl(base, 0, tr.seg); + if (cpu_state.abrt) + return; + } - new_cr3 = readmeml(base, 0x1C); - new_pc = readmeml(base, 0x20); - new_flags = readmeml(base, 0x24); - if ((optype == OPTYPE_INT) || (optype == CALL)) - new_flags |= NT_FLAG; + new_cr3 = readmeml(base, 0x1C); + new_pc = readmeml(base, 0x20); + new_flags = readmeml(base, 0x24); + if ((optype == OPTYPE_INT) || (optype == CALL)) + new_flags |= NT_FLAG; - new_eax = readmeml(base, 0x28); - new_ecx = readmeml(base, 0x2C); - new_edx = readmeml(base, 0x30); - new_ebx = readmeml(base, 0x34); - new_esp = readmeml(base, 0x38); - new_ebp = readmeml(base, 0x3C); - new_esi = readmeml(base, 0x40); - new_edi = readmeml(base, 0x44); + new_eax = readmeml(base, 0x28); + new_ecx = readmeml(base, 0x2C); + new_edx = readmeml(base, 0x30); + new_ebx = readmeml(base, 0x34); + new_esp = readmeml(base, 0x38); + new_ebp = readmeml(base, 0x3C); + new_esi = readmeml(base, 0x40); + new_edi = readmeml(base, 0x44); - new_es = readmemw(base, 0x48); - new_cs = readmemw(base, 0x4C); - new_ss = readmemw(base, 0x50); - new_ds = readmemw(base, 0x54); - new_fs = readmemw(base, 0x58); - new_gs = readmemw(base, 0x5C); - new_ldt = readmemw(base, 0x60); + new_es = readmemw(base, 0x48); + new_cs = readmemw(base, 0x4C); + new_ss = readmemw(base, 0x50); + new_ds = readmemw(base, 0x54); + new_fs = readmemw(base, 0x58); + new_gs = readmemw(base, 0x5C); + new_ldt = readmemw(base, 0x60); - cr0 |= 8; + cr0 |= 8; - cr3 = new_cr3; - flushmmucache(); + cr3 = new_cr3; + flushmmucache(); - cpu_state.pc = new_pc; - cpu_state.flags = new_flags; - cpu_state.eflags = new_flags >> 16; - cpu_386_flags_extract(); + cpu_state.pc = new_pc; + cpu_state.flags = new_flags; + cpu_state.eflags = new_flags >> 16; + cpu_386_flags_extract(); - ldt.seg = new_ldt; - templ = (ldt.seg & ~7) + gdt.base; - ldt.limit = readmemw(0, templ); - if (readmemb(0, templ + 6) & 0x80) { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16) | (readmemb(0, templ + 7) << 24); + ldt.seg = new_ldt; + templ = (ldt.seg & ~7) + gdt.base; + ldt.limit = readmemw(0, templ); + if (readmemb(0, templ + 6) & 0x80) { + ldt.limit <<= 12; + ldt.limit |= 0xfff; + } + ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16) | (readmemb(0, templ + 7) << 24); - if (cpu_state.eflags & VM_FLAG) { - loadcs(new_cs); - set_use32(0); - cpu_cur_status |= CPU_STATUS_V86; - } else { - if (!(new_cs & 0xfffc)) { - x86ts("taskswitch286(): New CS selector is null", 0); - return; - } - addr = new_cs & 0xfff8; - dt = (new_cs & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86ts("taskswitch286(): New CS selector > DT limit", new_cs & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 0); - if (!(segdat2[2] & 0x8000)) { - x86np("TS loading CS not present", new_cs & 0xfffc); - return; - } - switch (segdat2[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if ((new_cs & 0x0003) != DPL2) { - x86ts("TS loading CS RPL != DPL2", new_cs & 0xfffc); - return; - } - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if ((new_cs & 0x0003) < DPL2) { - x86ts("TS loading CS RPL < DPL2", new_cs & 0xfffc); - return; - } - break; - default: - x86ts("TS loading CS unknown type", new_cs & 0xfffc); - return; - } + if (cpu_state.eflags & VM_FLAG) { + loadcs(new_cs); + set_use32(0); + cpu_cur_status |= CPU_STATUS_V86; + } else { + if (!(new_cs & 0xfffc)) { + x86ts("taskswitch286(): New CS selector is null", 0); + return; + } + addr = new_cs & 0xfff8; + dt = (new_cs & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86ts("taskswitch286(): New CS selector > DT limit", new_cs & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 0); + if (!(segdat2[2] & 0x8000)) { + x86np("TS loading CS not present", new_cs & 0xfffc); + return; + } + switch (segdat2[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if ((new_cs & 0x0003) != DPL2) { + x86ts("TS loading CS RPL != DPL2", new_cs & 0xfffc); + return; + } + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if ((new_cs & 0x0003) < DPL2) { + x86ts("TS loading CS RPL < DPL2", new_cs & 0xfffc); + return; + } + break; + default: + x86ts("TS loading CS unknown type", new_cs & 0xfffc); + return; + } - CS = new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = new_cs; + do_seg_load(&cpu_state.seg_cs, segdat2); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat2[3] & 0x0040); - cpu_cur_status &= ~CPU_STATUS_V86; - } + set_use32(segdat2[3] & 0x0040); + cpu_cur_status &= ~CPU_STATUS_V86; + } - EAX = new_eax; - ECX = new_ecx; - EDX = new_edx; - EBX = new_ebx; - ESP = new_esp; - EBP = new_ebp; - ESI = new_esi; - EDI = new_edi; + EAX = new_eax; + ECX = new_ecx; + EDX = new_edx; + EBX = new_ebx; + ESP = new_esp; + EBP = new_ebp; + ESI = new_esi; + EDI = new_edi; - loadseg(new_es, &cpu_state.seg_es); - loadseg(new_ss, &cpu_state.seg_ss); - loadseg(new_ds, &cpu_state.seg_ds); - loadseg(new_fs, &cpu_state.seg_fs); - loadseg(new_gs, &cpu_state.seg_gs); + loadseg(new_es, &cpu_state.seg_es); + loadseg(new_ss, &cpu_state.seg_ss); + loadseg(new_ds, &cpu_state.seg_ds); + loadseg(new_fs, &cpu_state.seg_fs); + loadseg(new_gs, &cpu_state.seg_gs); } else { - if (limit < 43) { - x86ts(NULL, seg); - return; - } + if (limit < 43) { + x86ts(NULL, seg); + return; + } - if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw |= 0x200; - if (tr.seg & 0x0004) - writememw(ldt.base, (seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw |= 0x200; + if (tr.seg & 0x0004) + writememw(ldt.base, (seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if (optype == IRET) - cpu_state.flags &= ~NT_FLAG; + if (optype == IRET) + cpu_state.flags &= ~NT_FLAG; - cpu_386_flags_rebuild(); - writememw(tr.base, 0x0e, cpu_state.pc); - writememw(tr.base, 0x10, cpu_state.flags); + cpu_386_flags_rebuild(); + writememw(tr.base, 0x0e, cpu_state.pc); + writememw(tr.base, 0x10, cpu_state.flags); - writememw(tr.base, 0x12, AX); - writememw(tr.base, 0x14, CX); - writememw(tr.base, 0x16, DX); - writememw(tr.base, 0x18, BX); - writememw(tr.base, 0x1a, SP); - writememw(tr.base, 0x1c, BP); - writememw(tr.base, 0x1e, SI); - writememw(tr.base, 0x20, DI); + writememw(tr.base, 0x12, AX); + writememw(tr.base, 0x14, CX); + writememw(tr.base, 0x16, DX); + writememw(tr.base, 0x18, BX); + writememw(tr.base, 0x1a, SP); + writememw(tr.base, 0x1c, BP); + writememw(tr.base, 0x1e, SI); + writememw(tr.base, 0x20, DI); - writememw(tr.base, 0x22, ES); - writememw(tr.base, 0x24, CS); - writememw(tr.base, 0x26, SS); - writememw(tr.base, 0x28, DS); + writememw(tr.base, 0x22, ES); + writememw(tr.base, 0x24, CS); + writememw(tr.base, 0x26, SS); + writememw(tr.base, 0x28, DS); - if ((optype == JMP) || (optype == IRET)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw &= ~0x200; - if (tr.seg & 0x0004) - writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == IRET)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw &= ~0x200; + if (tr.seg & 0x0004) + writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if ((optype == OPTYPE_INT) || (optype == CALL)) { - writememw(base, 0, tr.seg); - if (cpu_state.abrt) - return; - } + if ((optype == OPTYPE_INT) || (optype == CALL)) { + writememw(base, 0, tr.seg); + if (cpu_state.abrt) + return; + } - new_pc = readmemw(base, 0x0e); - new_flags = readmemw(base, 0x10); - if ((optype == OPTYPE_INT) || (optype == CALL)) - new_flags |= NT_FLAG; + new_pc = readmemw(base, 0x0e); + new_flags = readmemw(base, 0x10); + if ((optype == OPTYPE_INT) || (optype == CALL)) + new_flags |= NT_FLAG; - new_eax = readmemw(base, 0x12); - new_ecx = readmemw(base, 0x14); - new_edx = readmemw(base, 0x16); - new_ebx = readmemw(base, 0x18); - new_esp = readmemw(base, 0x1a); - new_ebp = readmemw(base, 0x1c); - new_esi = readmemw(base, 0x1e); - new_edi = readmemw(base, 0x20); + new_eax = readmemw(base, 0x12); + new_ecx = readmemw(base, 0x14); + new_edx = readmemw(base, 0x16); + new_ebx = readmemw(base, 0x18); + new_esp = readmemw(base, 0x1a); + new_ebp = readmemw(base, 0x1c); + new_esi = readmemw(base, 0x1e); + new_edi = readmemw(base, 0x20); - new_es = readmemw(base, 0x22); - new_cs = readmemw(base, 0x24); - new_ss = readmemw(base, 0x26); - new_ds = readmemw(base, 0x28); - new_ldt = readmemw(base, 0x2a); + new_es = readmemw(base, 0x22); + new_cs = readmemw(base, 0x24); + new_ss = readmemw(base, 0x26); + new_ds = readmemw(base, 0x28); + new_ldt = readmemw(base, 0x2a); - msw |= 8; + msw |= 8; - cpu_state.pc = new_pc; - cpu_state.flags = new_flags; - cpu_386_flags_extract(); + cpu_state.pc = new_pc; + cpu_state.flags = new_flags; + cpu_386_flags_extract(); - ldt.seg = new_ldt; - templ = (ldt.seg & 0xfff8) + gdt.base; - ldt.limit = readmemw(0, templ); - ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16); - if (is386) { - if (readmemb(0, templ + 6) & 0x80) { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base |= (readmemb(0, templ + 7) << 24); - } + ldt.seg = new_ldt; + templ = (ldt.seg & 0xfff8) + gdt.base; + ldt.limit = readmemw(0, templ); + ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16); + if (is386) { + if (readmemb(0, templ + 6) & 0x80) { + ldt.limit <<= 12; + ldt.limit |= 0xfff; + } + ldt.base |= (readmemb(0, templ + 7) << 24); + } - if (!(new_cs & 0xfff8)) { - x86ts(NULL, 0); - return; - } - addr = new_cs & 0xfff8; - dt = (new_cs & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86ts(NULL, new_cs & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 0); - if (!(segdat2[2] & 0x8000)) { - x86np("TS loading CS not present", new_cs & 0xfffc); - return; - } - switch (segdat2[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if ((new_cs & 0x0003) != DPL2) { - x86ts(NULL,new_cs & 0xfffc); - return; - } - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if ((new_cs & 0x0003) < DPL2) { - x86ts(NULL,new_cs & 0xfffc); - return; - } - break; - default: - x86ts(NULL, new_cs & 0xfffc); - return; - } + if (!(new_cs & 0xfff8)) { + x86ts(NULL, 0); + return; + } + addr = new_cs & 0xfff8; + dt = (new_cs & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86ts(NULL, new_cs & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 0); + if (!(segdat2[2] & 0x8000)) { + x86np("TS loading CS not present", new_cs & 0xfffc); + return; + } + switch (segdat2[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if ((new_cs & 0x0003) != DPL2) { + x86ts(NULL, new_cs & 0xfffc); + return; + } + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if ((new_cs & 0x0003) < DPL2) { + x86ts(NULL, new_cs & 0xfffc); + return; + } + break; + default: + x86ts(NULL, new_cs & 0xfffc); + return; + } - CS = new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = new_cs; + do_seg_load(&cpu_state.seg_cs, segdat2); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(0); + set_use32(0); - EAX = new_eax | 0xffff0000; - ECX = new_ecx | 0xffff0000; - EDX = new_edx | 0xffff0000; - EBX = new_ebx | 0xffff0000; - ESP = new_esp | 0xffff0000; - EBP = new_ebp | 0xffff0000; - ESI = new_esi | 0xffff0000; - EDI = new_edi | 0xffff0000; + EAX = new_eax | 0xffff0000; + ECX = new_ecx | 0xffff0000; + EDX = new_edx | 0xffff0000; + EBX = new_ebx | 0xffff0000; + ESP = new_esp | 0xffff0000; + EBP = new_ebp | 0xffff0000; + ESI = new_esi | 0xffff0000; + EDI = new_edi | 0xffff0000; - loadseg(new_es, &cpu_state.seg_es); - loadseg(new_ss, &cpu_state.seg_ss); - loadseg(new_ds, &cpu_state.seg_ds); - if (is386) { - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); - } + loadseg(new_es, &cpu_state.seg_es); + loadseg(new_ss, &cpu_state.seg_ss); + loadseg(new_ds, &cpu_state.seg_ds); + if (is386) { + loadseg(0, &cpu_state.seg_fs); + loadseg(0, &cpu_state.seg_gs); + } } - tr.seg = seg; - tr.base = base; - tr.limit = limit; - tr.access = segdat[2] >> 8; + tr.seg = seg; + tr.base = base; + tr.limit = limit; + tr.access = segdat[2] >> 8; tr.ar_high = segdat[3] & 0xff; } - void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) { uint32_t limit_raw = seg->limit; if (seg->ar_high & 0x80) - limit_raw >>= 12; + limit_raw >>= 12; writememl(0, addr, (limit_raw & 0xffff) | (seg->base << 16)); - writememl(0, addr + 4, ((seg->base >> 16) & 0xff) | (seg->access << 8) | - (limit_raw & 0xf0000) | (seg->ar_high << 16) | - (seg->base & 0xff000000)); + writememl(0, addr + 4, ((seg->base >> 16) & 0xff) | (seg->access << 8) | (limit_raw & 0xf0000) | (seg->ar_high << 16) | (seg->base & 0xff000000)); } - void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) { @@ -2414,30 +2453,30 @@ cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) segdat[1] = readmemw(0, addr + 2); segdat[2] = readmemw(0, addr + 4); segdat[3] = readmemw(0, addr + 6); - selector = readmemw(0, addr+8); + selector = readmemw(0, addr + 8); if (!cpu_state.abrt) { - do_seg_load(seg, segdat); - seg->seg = selector; - seg->checked = 0; - if (seg == &cpu_state.seg_ds) { - if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + do_seg_load(seg, segdat); + seg->seg = selector; + seg->checked = 0; + if (seg == &cpu_state.seg_ds) { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; #ifdef USE_DYNAREC - codegen_flat_ds = 0; + codegen_flat_ds = 0; #endif - } - if (seg == &cpu_state.seg_ss) { - if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - set_stack32((segdat[3] & 0x40) ? 1 : 0); + } + if (seg == &cpu_state.seg_ss) { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + set_stack32((segdat[3] & 0x40) ? 1 : 0); #ifdef USE_DYNAREC - codegen_flat_ss = 0; + codegen_flat_ss = 0; #endif - } + } } } diff --git a/src/cpu/x86seg.h b/src/cpu/x86seg.h index d98db1586..715251f2d 100644 --- a/src/cpu/x86seg.h +++ b/src/cpu/x86seg.h @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * x86 CPU segment emulation. + * x86 CPU segment emulation. * * * - * Author: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 Miran Grca. */ extern void do_seg_load(x86seg *s, uint16_t *segdat); diff --git a/src/cpu/x87.c b/src/cpu/x87.c index cf92788fb..0b93af9da 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -16,117 +16,111 @@ #include "x87.h" #include "386_common.h" - -uint32_t x87_pc_off,x87_op_off; -uint16_t x87_pc_seg,x87_op_seg; - +uint32_t x87_pc_off, x87_op_off; +uint16_t x87_pc_seg, x87_op_seg; #ifdef ENABLE_FPU_LOG int fpu_do_log = ENABLE_FPU_LOG; - void fpu_log(const char *fmt, ...) { va_list ap; if (fpu_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define fpu_log(fmt, ...) +# define fpu_log(fmt, ...) #endif - #define X87_TAG_VALID 0 #define X87_TAG_ZERO 1 #define X87_TAG_INVALID 2 #define X87_TAG_EMPTY 3 #ifdef USE_NEW_DYNAREC -uint16_t x87_gettag() +uint16_t +x87_gettag(void) { - uint16_t ret = 0; - int c; + uint16_t ret = 0; + int c; - for (c = 0; c < 8; c++) - { - if (cpu_state.tag[c] == TAG_EMPTY) - ret |= X87_TAG_EMPTY << (c * 2); - else if (cpu_state.tag[c] & TAG_UINT64) - ret |= 2 << (c*2); - else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) - ret |= X87_TAG_ZERO << (c * 2); - else - ret |= X87_TAG_VALID << (c * 2); - } + for (c = 0; c < 8; c++) { + if (cpu_state.tag[c] == TAG_EMPTY) + ret |= X87_TAG_EMPTY << (c * 2); + else if (cpu_state.tag[c] & TAG_UINT64) + ret |= 2 << (c * 2); + else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) + ret |= X87_TAG_ZERO << (c * 2); + else + ret |= X87_TAG_VALID << (c * 2); + } - return ret; + return ret; } -void x87_settag(uint16_t new_tag) +void +x87_settag(uint16_t new_tag) { - int c; + int c; - for (c = 0; c < 8; c++) - { - int tag = (new_tag >> (c * 2)) & 3; + for (c = 0; c < 8; c++) { + int tag = (new_tag >> (c * 2)) & 3; - if (tag == X87_TAG_EMPTY) - cpu_state.tag[c] = TAG_EMPTY; - else if (tag == 2) - cpu_state.tag[c] = TAG_VALID | TAG_UINT64; - else - cpu_state.tag[c] = TAG_VALID; - } + if (tag == X87_TAG_EMPTY) + cpu_state.tag[c] = TAG_EMPTY; + else if (tag == 2) + cpu_state.tag[c] = TAG_VALID | TAG_UINT64; + else + cpu_state.tag[c] = TAG_VALID; + } } #else -uint16_t x87_gettag() +uint16_t +x87_gettag(void) { - uint16_t ret = 0; - int c; + uint16_t ret = 0; + int c; - for (c = 0; c < 8; c++) - { - if (cpu_state.tag[c] & TAG_UINT64) - ret |= 2 << (c*2); - else - ret |= (cpu_state.tag[c] << (c*2)); - } + for (c = 0; c < 8; c++) { + if (cpu_state.tag[c] & TAG_UINT64) + ret |= 2 << (c * 2); + else + ret |= (cpu_state.tag[c] << (c * 2)); + } - return ret; + return ret; } -void x87_settag(uint16_t new_tag) +void +x87_settag(uint16_t new_tag) { - cpu_state.tag[0] = new_tag & 3; - cpu_state.tag[1] = (new_tag >> 2) & 3; - cpu_state.tag[2] = (new_tag >> 4) & 3; - cpu_state.tag[3] = (new_tag >> 6) & 3; - cpu_state.tag[4] = (new_tag >> 8) & 3; - cpu_state.tag[5] = (new_tag >> 10) & 3; - cpu_state.tag[6] = (new_tag >> 12) & 3; - cpu_state.tag[7] = (new_tag >> 14) & 3; + cpu_state.tag[0] = new_tag & 3; + cpu_state.tag[1] = (new_tag >> 2) & 3; + cpu_state.tag[2] = (new_tag >> 4) & 3; + cpu_state.tag[3] = (new_tag >> 6) & 3; + cpu_state.tag[4] = (new_tag >> 8) & 3; + cpu_state.tag[5] = (new_tag >> 10) & 3; + cpu_state.tag[6] = (new_tag >> 12) & 3; + cpu_state.tag[7] = (new_tag >> 14) & 3; } #endif - #ifdef ENABLE_808X_LOG -void x87_dumpregs() +void +x87_dumpregs(void) { - if (cpu_state.ismmx) - { - fpu_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q); - fpu_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); - } - else - { - fpu_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",cpu_state.ST[cpu_state.TOP],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]); - fpu_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7]); - } - fpu_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag()); + if (cpu_state.ismmx) { + fpu_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q); + fpu_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); + } else { + fpu_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n", cpu_state.ST[cpu_state.TOP], cpu_state.ST[(cpu_state.TOP + 1) & 7], cpu_state.ST[(cpu_state.TOP + 2) & 7], cpu_state.ST[(cpu_state.TOP + 3) & 7]); + fpu_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n", cpu_state.ST[(cpu_state.TOP + 4) & 7], cpu_state.ST[(cpu_state.TOP + 5) & 7], cpu_state.ST[(cpu_state.TOP + 6) & 7], cpu_state.ST[(cpu_state.TOP + 7) & 7]); + } + fpu_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag()); } #endif diff --git a/src/cpu/x87.h b/src/cpu/x87.h index 9436d0447..96ad835c8 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -1,43 +1,44 @@ -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) -extern uint32_t x87_pc_off,x87_op_off; -extern uint16_t x87_pc_seg,x87_op_seg; +extern uint32_t x87_pc_off, x87_op_off; +extern uint16_t x87_pc_seg, x87_op_seg; -static __inline void x87_set_mmx() +static __inline void +x87_set_mmx(void) { - uint64_t *p; - cpu_state.TOP = 0; - p = (uint64_t *)cpu_state.tag; - *p = 0x0101010101010101ull; - cpu_state.ismmx = 1; + uint64_t *p; + cpu_state.TOP = 0; + p = (uint64_t *) cpu_state.tag; + *p = 0x0101010101010101ull; + cpu_state.ismmx = 1; } -static __inline void x87_emms() +static __inline void +x87_emms(void) { - uint64_t *p; - p = (uint64_t *)cpu_state.tag; - *p = 0; - cpu_state.ismmx = 0; + uint64_t *p; + p = (uint64_t *) cpu_state.tag; + *p = 0; + cpu_state.ismmx = 0; } +uint16_t x87_gettag(void); +void x87_settag(uint16_t new_tag); -uint16_t x87_gettag(); -void x87_settag(uint16_t new_tag); - -#define TAG_EMPTY 0 -#define TAG_VALID (1 << 0) +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) /*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ #ifdef USE_NEW_DYNAREC -#define TAG_UINT64 (1 << 7) +# define TAG_UINT64 (1 << 7) #else -#define TAG_UINT64 (1 << 2) +# define TAG_UINT64 (1 << 2) #endif /*Old dynarec stuff.*/ -#define TAG_NOT_UINT64 0xfb +#define TAG_NOT_UINT64 0xfb #define X87_ROUNDING_NEAREST 0 #define X87_ROUNDING_DOWN 1 diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 758546e7a..ce4a4becc 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -1,466 +1,469 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * x87 FPU instructions core. + * x87 FPU instructions core. * - * Version: @(#)x87_ops.h 1.0.8 2019/06/11 * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * leilei, - * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 leilei. - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 Fred N. van Kempen. + * Authors: Fred N. van Kempen, + * Sarah Walker, + * leilei, + * Miran Grca, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 leilei. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018-2019 Fred N. van Kempen. */ #include #include #include "x87_timings.h" #ifdef _MSC_VER -# include +# include #endif #ifdef ENABLE_FPU_LOG -extern void fpu_log(const char *fmt, ...); +extern void fpu_log(const char *fmt, ...); #else -#ifndef fpu_log -#define fpu_log(fmt, ...) -#endif +# ifndef fpu_log +# define fpu_log(fmt, ...) +# endif #endif -static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO}; +static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO }; -#define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] +#define ST(x) cpu_state.ST[((cpu_state.TOP + (x)) & 7)] -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) #define STATUS_ZERODIVIDE 4 #if defined(_MSC_VER) && !defined(__clang__) -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -# define X87_INLINE_ASM -# endif +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 +# define X87_INLINE_ASM +# endif #else -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__ -# define X87_INLINE_ASM -# endif +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__ +# define X87_INLINE_ASM +# endif #endif #ifdef FPU_8087 -#define x87_div(dst, src1, src2) do \ - { \ - if (((double)src2) == 0.0) \ - { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ - dst = src1 / (double)src2; \ - else \ - { \ - fpu_log("FPU : divide by zero\n"); \ - if (!(cpu_state.npxc & 0x80)) { \ - cpu_state.npxs |= 0x80; \ - nmi = 1; \ - } \ - return 1; \ - } \ - } \ - else \ - dst = src1 / (double)src2; \ +# define x87_div(dst, src1, src2) \ + do { \ + if (((double) src2) == 0.0) { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double) src2; \ + else { \ + fpu_log("FPU : divide by zero\n"); \ + if (!(cpu_state.npxc & 0x80)) { \ + cpu_state.npxs |= 0x80; \ + nmi = 1; \ + } \ + return 1; \ + } \ + } else \ + dst = src1 / (double) src2; \ } while (0) #else -#define x87_div(dst, src1, src2) do \ - { \ - if (((double)src2) == 0.0) \ - { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ - dst = src1 / (double)src2; \ - else \ - { \ - fpu_log("FPU : divide by zero\n"); \ - picint(1 << 13); \ - return 1; \ - } \ - } \ - else \ - dst = src1 / (double)src2; \ +# define x87_div(dst, src1, src2) \ + do { \ + if (((double) src2) == 0.0) { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double) src2; \ + else { \ + fpu_log("FPU : divide by zero\n"); \ + picint(1 << 13); \ + return 1; \ + } \ + } else \ + dst = src1 / (double) src2; \ } while (0) #endif -static __inline void x87_checkexceptions() +static __inline void +x87_checkexceptions(void) { } -static __inline void x87_push(double i) +static __inline void +x87_push(double i) { #ifdef USE_NEW_DYNAREC - cpu_state.TOP--; + cpu_state.TOP--; #else - cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.TOP = (cpu_state.TOP - 1) & 7; #endif - cpu_state.ST[cpu_state.TOP&7] = i; + cpu_state.ST[cpu_state.TOP & 7] = i; #ifdef USE_NEW_DYNAREC - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; #else - cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? TAG_VALID : 0; + cpu_state.tag[cpu_state.TOP & 7] = (i == 0.0) ? TAG_VALID : 0; #endif } -static __inline void x87_push_u64(uint64_t i) +static __inline void +x87_push_u64(uint64_t i) { - union - { - double d; - uint64_t ll; - } td; + union { + double d; + uint64_t ll; + } td; - td.ll = i; + td.ll = i; #ifdef USE_NEW_DYNAREC - cpu_state.TOP--; + cpu_state.TOP--; #else - cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.TOP = (cpu_state.TOP - 1) & 7; #endif - cpu_state.ST[cpu_state.TOP&7] = td.d; + cpu_state.ST[cpu_state.TOP & 7] = td.d; #ifdef USE_NEW_DYNAREC - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; #else - cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? TAG_VALID : 0; + cpu_state.tag[cpu_state.TOP & 7] = (td.d == 0.0) ? TAG_VALID : 0; #endif } -static __inline double x87_pop() +static __inline double +x87_pop(void) { - double t = cpu_state.ST[cpu_state.TOP&7]; - cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; + double t = cpu_state.ST[cpu_state.TOP & 7]; + cpu_state.tag[cpu_state.TOP & 7] = TAG_EMPTY; #ifdef USE_NEW_DYNAREC - cpu_state.TOP++; + cpu_state.TOP++; #else - cpu_state.tag[cpu_state.TOP&7] |= TAG_UINT64; - cpu_state.TOP=(cpu_state.TOP+1)&7; + cpu_state.tag[cpu_state.TOP & 7] |= TAG_UINT64; + cpu_state.TOP = (cpu_state.TOP + 1) & 7; #endif - return t; + return t; } -static __inline int16_t x87_fround16(double b) +static __inline int16_t +x87_fround16(double b) { - int16_t a, c; + int16_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int16_t)floor(b); - c = (int16_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int16_t)floor(b); - case 2: /*Up*/ - return (int16_t)ceil(b); - case 3: /*Chop*/ - return (int16_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int16_t) floor(b); + c = (int16_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int16_t) floor(b); + case 2: /*Up*/ + return (int16_t) ceil(b); + case 3: /*Chop*/ + return (int16_t) b; + } - return 0; + return 0; } -static __inline int64_t x87_fround16_64(double b) +static __inline int64_t +x87_fround16_64(double b) { return (int64_t) x87_fround16(b); } -static __inline int32_t x87_fround32(double b) +static __inline int32_t +x87_fround32(double b) { - int32_t a, c; + int32_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int32_t)floor(b); - c = (int32_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int32_t)floor(b); - case 2: /*Up*/ - return (int32_t)ceil(b); - case 3: /*Chop*/ - return (int32_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int32_t) floor(b); + c = (int32_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int32_t) floor(b); + case 2: /*Up*/ + return (int32_t) ceil(b); + case 3: /*Chop*/ + return (int32_t) b; + } - return 0; + return 0; } -static __inline int64_t x87_fround32_64(double b) +static __inline int64_t +x87_fround32_64(double b) { return (int64_t) x87_fround32(b); } -static __inline int64_t x87_fround(double b) +static __inline int64_t +x87_fround(double b) { - int64_t a, c; + int64_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int64_t) floor(b); + c = (int64_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) floor(b); + case 2: /*Up*/ + return (int64_t) ceil(b); + case 3: /*Chop*/ + return (int64_t) b; + } - return 0LL; + return 0LL; } #include "x87_ops_conv.h" -static __inline double x87_ld80() +static __inline double +x87_ld80(void) { - x87_conv_t test; - test.eind.ll = readmeml(easeg,cpu_state.eaaddr); - test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; - test.begin = readmemw(easeg,cpu_state.eaaddr+8); - return x87_from80(&test); + x87_conv_t test; + test.eind.ll = readmeml(easeg, cpu_state.eaaddr); + test.eind.ll |= (uint64_t) readmeml(easeg, cpu_state.eaaddr + 4) << 32; + test.begin = readmemw(easeg, cpu_state.eaaddr + 8); + return x87_from80(&test); } -static __inline void x87_st80(double d) +static __inline void +x87_st80(double d) { - x87_conv_t test; - x87_to80(d, &test); - writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff); - writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32); - writememw(easeg,cpu_state.eaaddr+8,test.begin); + x87_conv_t test; + x87_to80(d, &test); + writememl(easeg, cpu_state.eaaddr, test.eind.ll & 0xffffffff); + writememl(easeg, cpu_state.eaaddr + 4, test.eind.ll >> 32); + writememw(easeg, cpu_state.eaaddr + 8, test.begin); } -static __inline void x87_st_fsave(int reg) +static __inline void +x87_st_fsave(int reg) { - reg = (cpu_state.TOP + reg) & 7; + reg = (cpu_state.TOP + reg) & 7; - if (cpu_state.tag[reg] & TAG_UINT64) - { - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff); - writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32); - writememw(easeg, cpu_state.eaaddr + 8, 0x5555); - } - else - x87_st80(cpu_state.ST[reg]); + if (cpu_state.tag[reg] & TAG_UINT64) { + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff); + writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32); + writememw(easeg, cpu_state.eaaddr + 8, 0x5555); + } else + x87_st80(cpu_state.ST[reg]); } -static __inline void x87_ld_frstor(int reg) +static __inline void +x87_ld_frstor(int reg) { - reg = (cpu_state.TOP + reg) & 7; + reg = (cpu_state.TOP + reg) & 7; - cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); - cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); + cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); + cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); #ifdef USE_NEW_DYNAREC - if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) #else - if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2)) + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2)) #endif - { + { #ifndef USE_NEW_DYNAREC - cpu_state.tag[reg] = TAG_UINT64; + cpu_state.tag[reg] = TAG_UINT64; #endif - cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; - } - else - { + cpu_state.ST[reg] = (double) cpu_state.MM[reg].q; + } else { #ifdef USE_NEW_DYNAREC - cpu_state.tag[reg] &= ~TAG_UINT64; + cpu_state.tag[reg] &= ~TAG_UINT64; #endif - cpu_state.ST[reg] = x87_ld80(); - } + cpu_state.ST[reg] = x87_ld80(); + } } -static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) +static __inline void +x87_ldmmx(MMX_REG *r, uint16_t *w4) { - r->l[0] = readmeml(easeg, cpu_state.eaaddr); - r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - *w4 = readmemw(easeg, cpu_state.eaaddr + 8); + r->l[0] = readmeml(easeg, cpu_state.eaaddr); + r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + *w4 = readmemw(easeg, cpu_state.eaaddr + 8); } -static __inline void x87_stmmx(MMX_REG r) +static __inline void +x87_stmmx(MMX_REG r) { - writememl(easeg, cpu_state.eaaddr, r.l[0]); - writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); - writememw(easeg, cpu_state.eaaddr + 8, 0xffff); + writememl(easeg, cpu_state.eaaddr, r.l[0]); + writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); + writememw(easeg, cpu_state.eaaddr + 8, 0xffff); } #include -static __inline uint16_t x87_compare(double a, double b) +static __inline uint16_t +x87_compare(double a, double b) { #ifdef X87_INLINE_ASM - uint32_t result; - double ea = a, eb = b; - const uint64_t ia = 0x3fec1a6ff866a936ull; - const uint64_t ib = 0x3fec1a6ff866a938ull; + uint32_t result; + double ea = a, eb = b; + const uint64_t ia = 0x3fec1a6ff866a936ull; + const uint64_t ib = 0x3fec1a6ff866a938ull; - /* Hack to make CHKCOP happy. */ - if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) - return C3; + /* Hack to make CHKCOP happy. */ + if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) + return C3; - if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && - ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) - eb = ea; + if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; -#if !defined(_MSC_VER) || defined(__clang__) - /* Memory barrier, to force GCC to write to the input parameters - * before the compare rather than after */ - __asm volatile ("" : : : "memory"); +# if !defined(_MSC_VER) || defined(__clang__) + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + __asm volatile("" + : + : + : "memory"); - __asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fcompp\n" - "fnstsw %0\n" - : "=m" (result) - : "m" (ea), "m" (eb) - ); -#else - _ReadWriteBarrier(); - _asm - { + __asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fcompp\n" + "fnstsw %0\n" + : "=m"(result) + : "m"(ea), "m"(eb)); +# else + _ReadWriteBarrier(); + _asm + { fld eb fld ea fclex fcompp fnstsw result - } -#endif + } +# endif - return result & (C0|C2|C3); + return result & (C0 | C2 | C3); #else - /* Generic C version is known to give incorrect results in some - * situations, eg comparison of infinity (Unreal) */ - uint32_t result = 0; - double ea = a, eb = b; + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; + double ea = a, eb = b; - if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && - ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) - eb = ea; + if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; - if (ea == eb) - result |= C3; - else if (ea < eb) - result |= C0; + if (ea == eb) + result |= C3; + else if (ea < eb) + result |= C0; - return result; + return result; #endif } -static __inline uint16_t x87_ucompare(double a, double b) +static __inline uint16_t +x87_ucompare(double a, double b) { #ifdef X87_INLINE_ASM - uint32_t result; + uint32_t result; -#if !defined(_MSC_VER) || defined(__clang__) - /* Memory barrier, to force GCC to write to the input parameters - * before the compare rather than after */ - __asm volatile ("" : : : "memory"); +# if !defined(_MSC_VER) || defined(__clang__) + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + __asm volatile("" + : + : + : "memory"); - __asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fucompp\n" - "fnstsw %0\n" - : "=m" (result) - : "m" (a), "m" (b) - ); -#else - _ReadWriteBarrier(); - _asm - { + __asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fucompp\n" + "fnstsw %0\n" + : "=m"(result) + : "m"(a), "m"(b)); +# else + _ReadWriteBarrier(); + _asm + { fld b fld a fclex fcompp fnstsw result - } -#endif + } +# endif - return result & (C0|C2|C3); + return result & (C0 | C2 | C3); #else - /* Generic C version is known to give incorrect results in some - * situations, eg comparison of infinity (Unreal) */ - uint32_t result = 0; + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; - if (a == b) - result |= C3; - else if (a < b) - result |= C0; + if (a == b) + result |= C3; + else if (a < b) + result |= C0; - return result; + return result; #endif } -typedef union -{ - float s; - uint32_t i; +typedef union { + float s; + uint32_t i; } x87_ts; -typedef union -{ - double d; - uint64_t i; +typedef union { + double d; + uint64_t i; } x87_td; #ifdef FPU_8087 -#define FP_ENTER() { \ - } +# define FP_ENTER() \ + { \ + } #else -#define FP_ENTER() do \ - { \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ +# define FP_ENTER() \ + do { \ + if (cr0 & 0xc) { \ + x86_int(7); \ + return 1; \ + } \ } while (0) #endif #ifdef USE_NEW_DYNAREC -# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP&7] = TAG_VALID -# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID -# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64 -# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID +# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID +# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID +# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID | TAG_UINT64 +# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID #else -# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64 -# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64 -# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; -# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64 +# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64 +# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64 +# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; +# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64 #endif #include "x87_ops_arith.h" @@ -468,72 +471,72 @@ typedef union #include "x87_ops_loadstore.h" #ifndef FPU_8087 -static int op_nofpu_a16(uint32_t fetchdat) +static int +op_nofpu_a16(uint32_t fetchdat) { - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - else - { - fetch_ea_16(fetchdat); - return 0; - } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } else { + fetch_ea_16(fetchdat); + return 0; + } } -static int op_nofpu_a32(uint32_t fetchdat) +static int +op_nofpu_a32(uint32_t fetchdat) { - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - else - { - fetch_ea_32(fetchdat); - return 0; - } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } else { + fetch_ea_32(fetchdat); + return 0; + } } #endif #ifdef FPU_8087 -static int FPU_ILLEGAL_a16(uint32_t fetchdat) +static int +FPU_ILLEGAL_a16(uint32_t fetchdat) { - geteaw(); - wait(timing_rr, 0); - return 0; + geteaw(); + wait(timing_rr, 0); + return 0; } #else -static int FPU_ILLEGAL_a16(uint32_t fetchdat) +static int +FPU_ILLEGAL_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; + fetch_ea_16(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -static int FPU_ILLEGAL_a32(uint32_t fetchdat) +static int +FPU_ILLEGAL_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; + fetch_ea_32(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } #endif #define ILLEGAL_a16 FPU_ILLEGAL_a16 #ifdef FPU_8087 -const OpFn OP_TABLE(fpu_8087_d8)[32] = -{ +const OpFn OP_TABLE(fpu_8087_d8)[32] = { + // clang-format off opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_d9)[256] = -{ +const OpFn OP_TABLE(fpu_8087_d9)[256] = { + // clang-format off opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, @@ -569,10 +572,11 @@ const OpFn OP_TABLE(fpu_8087_d9)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, ILLEGAL_a16, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16 + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_da)[256] = -{ +const OpFn OP_TABLE(fpu_8087_da)[256] = { + // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -608,10 +612,11 @@ const OpFn OP_TABLE(fpu_8087_da)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_db)[256] = -{ +const OpFn OP_TABLE(fpu_8087_db)[256] = { + // clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -647,18 +652,20 @@ const OpFn OP_TABLE(fpu_8087_db)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_dc)[32] = -{ +const OpFn OP_TABLE(fpu_8087_dc)[32] = { + // clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_dd)[256] = -{ +const OpFn OP_TABLE(fpu_8087_dd)[256] = { + // clang-format off opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, @@ -694,10 +701,11 @@ const OpFn OP_TABLE(fpu_8087_dd)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_de)[256] = -{ +const OpFn OP_TABLE(fpu_8087_de)[256] = { + // clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, @@ -733,10 +741,11 @@ const OpFn OP_TABLE(fpu_8087_de)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_df)[256] = -{ +const OpFn OP_TABLE(fpu_8087_df)[256] = { + // clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -772,27 +781,31 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; #else -#define ILLEGAL_a32 FPU_ILLEGAL_a32 +# define ILLEGAL_a32 FPU_ILLEGAL_a32 -const OpFn OP_TABLE(fpu_d8_a16)[32] = -{ +const OpFn OP_TABLE(fpu_d8_a16)[32] = { + // clang-format off opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR + // clang-format on }; -const OpFn OP_TABLE(fpu_d8_a32)[32] = -{ + +const OpFn OP_TABLE(fpu_d8_a32)[32] = { + // clang-format off opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR + // clang-format on }; -const OpFn OP_TABLE(fpu_287_d9_a16)[256] = -{ +const OpFn OP_TABLE(fpu_287_d9_a16)[256] = { + // clang-format off opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, @@ -828,10 +841,11 @@ const OpFn OP_TABLE(fpu_287_d9_a16)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + // clang-format on }; -const OpFn OP_TABLE(fpu_287_d9_a32)[256] = -{ +const OpFn OP_TABLE(fpu_287_d9_a32)[256] = { + // clang-format off opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, @@ -867,10 +881,11 @@ const OpFn OP_TABLE(fpu_287_d9_a32)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + // clang-format on }; -const OpFn OP_TABLE(fpu_d9_a16)[256] = -{ +const OpFn OP_TABLE(fpu_d9_a16)[256] = { + // clang-format off opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, @@ -906,10 +921,11 @@ const OpFn OP_TABLE(fpu_d9_a16)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + // clang-format on }; -const OpFn OP_TABLE(fpu_d9_a32)[256] = -{ +const OpFn OP_TABLE(fpu_d9_a32)[256] = { + // clang-format off opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, @@ -945,10 +961,11 @@ const OpFn OP_TABLE(fpu_d9_a32)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + // clang-format on }; -const OpFn OP_TABLE(fpu_287_da_a16)[256] = -{ +const OpFn OP_TABLE(fpu_287_da_a16)[256] = { + // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -984,48 +1001,51 @@ const OpFn OP_TABLE(fpu_287_da_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -}; -const OpFn OP_TABLE(fpu_287_da_a32)[256] = -{ - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, - opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, - opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, - opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, - opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, - opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, - opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, - opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_da_a16)[256] = -{ +const OpFn OP_TABLE(fpu_287_da_a32)[256] = { + // clang-format off + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on +}; + +const OpFn OP_TABLE(fpu_da_a16)[256] = { + // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -1061,9 +1081,11 @@ const OpFn OP_TABLE(fpu_da_a16)[256] = ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_da_a32)[256] = -{ + +const OpFn OP_TABLE(fpu_da_a32)[256] = { + // clang-format off opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, @@ -1099,10 +1121,11 @@ const OpFn OP_TABLE(fpu_da_a32)[256] = ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_686_da_a16)[256] = -{ +const OpFn OP_TABLE(fpu_686_da_a16)[256] = { + // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -1138,9 +1161,11 @@ const OpFn OP_TABLE(fpu_686_da_a16)[256] = ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_686_da_a32)[256] = -{ + +const OpFn OP_TABLE(fpu_686_da_a32)[256] = { + // clang-format off opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, @@ -1176,10 +1201,11 @@ const OpFn OP_TABLE(fpu_686_da_a32)[256] = ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_287_db_a16)[256] = -{ +const OpFn OP_TABLE(fpu_287_db_a16)[256] = { + // clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -1215,9 +1241,11 @@ const OpFn OP_TABLE(fpu_287_db_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_287_db_a32)[256] = -{ + +const OpFn OP_TABLE(fpu_287_db_a32)[256] = { + // clang-format off opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, @@ -1253,10 +1281,11 @@ const OpFn OP_TABLE(fpu_287_db_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_db_a16)[256] = -{ +const OpFn OP_TABLE(fpu_db_a16)[256] = { + // clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -1292,9 +1321,11 @@ const OpFn OP_TABLE(fpu_db_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_db_a32)[256] = -{ + +const OpFn OP_TABLE(fpu_db_a32)[256] = { + // clang-format off opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, @@ -1330,10 +1361,11 @@ const OpFn OP_TABLE(fpu_db_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_686_db_a16)[256] = -{ +const OpFn OP_TABLE(fpu_686_db_a16)[256] = { + // clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -1369,9 +1401,10 @@ const OpFn OP_TABLE(fpu_686_db_a16)[256] = opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_686_db_a32)[256] = -{ +const OpFn OP_TABLE(fpu_686_db_a32)[256] = { + // clang-format off opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, @@ -1407,40 +1440,47 @@ const OpFn OP_TABLE(fpu_686_db_a32)[256] = opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_287_dc_a16)[32] = -{ +const OpFn OP_TABLE(fpu_287_dc_a16)[32] = { + // clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr + // clang-format on }; -const OpFn OP_TABLE(fpu_287_dc_a32)[32] = -{ + +const OpFn OP_TABLE(fpu_287_dc_a32)[32] = { + // clang-format off opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDr, opFMULr, ILLEGAL_a32, ILLEGAL_a32, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr + // clang-format on }; -const OpFn OP_TABLE(fpu_dc_a16)[32] = -{ +const OpFn OP_TABLE(fpu_dc_a16)[32] = { + // clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr + // clang-format on }; -const OpFn OP_TABLE(fpu_dc_a32)[32] = -{ + +const OpFn OP_TABLE(fpu_dc_a32)[32] = { + // clang-format off opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr + // clang-format on }; -const OpFn OP_TABLE(fpu_287_dd_a16)[256] = -{ +const OpFn OP_TABLE(fpu_287_dd_a16)[256] = { + // clang-format off opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, @@ -1476,9 +1516,11 @@ const OpFn OP_TABLE(fpu_287_dd_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_287_dd_a32)[256] = -{ + +const OpFn OP_TABLE(fpu_287_dd_a32)[256] = { + // clang-format off opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, @@ -1514,10 +1556,11 @@ const OpFn OP_TABLE(fpu_287_dd_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_dd_a16)[256] = -{ +const OpFn OP_TABLE(fpu_dd_a16)[256] = { + // clang-format off opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, @@ -1553,9 +1596,11 @@ const OpFn OP_TABLE(fpu_dd_a16)[256] = opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_dd_a32)[256] = -{ + +const OpFn OP_TABLE(fpu_dd_a32)[256] = { + // clang-format off opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, @@ -1591,10 +1636,11 @@ const OpFn OP_TABLE(fpu_dd_a32)[256] = opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_287_de_a16)[256] = -{ +const OpFn OP_TABLE(fpu_287_de_a16)[256] = { + // clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, @@ -1630,10 +1676,11 @@ const OpFn OP_TABLE(fpu_287_de_a16)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, + // clang-format on }; -const OpFn OP_TABLE(fpu_287_de_a32)[256] = -{ +const OpFn OP_TABLE(fpu_287_de_a32)[256] = { + // clang-format off opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, @@ -1669,10 +1716,11 @@ const OpFn OP_TABLE(fpu_287_de_a32)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, + // clang-format on }; -const OpFn OP_TABLE(fpu_de_a16)[256] = -{ +const OpFn OP_TABLE(fpu_de_a16)[256] = { + // clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, @@ -1708,10 +1756,11 @@ const OpFn OP_TABLE(fpu_de_a16)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, + // clang-format on }; -const OpFn OP_TABLE(fpu_de_a32)[256] = -{ +const OpFn OP_TABLE(fpu_de_a32)[256] = { + // clang-format off opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, @@ -1747,10 +1796,11 @@ const OpFn OP_TABLE(fpu_de_a32)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, + // clang-format on }; -const OpFn OP_TABLE(fpu_287_df_a16)[256] = -{ +const OpFn OP_TABLE(fpu_287_df_a16)[256] = { + // clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -1786,9 +1836,11 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_287_df_a32)[256] = -{ + +const OpFn OP_TABLE(fpu_287_df_a32)[256] = { + // clang-format off opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, @@ -1824,10 +1876,11 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_df_a16)[256] = -{ +const OpFn OP_TABLE(fpu_df_a16)[256] = { + // clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -1863,9 +1916,11 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_df_a32)[256] = -{ + +const OpFn OP_TABLE(fpu_df_a32)[256] = { + // clang-format off opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, @@ -1901,10 +1956,11 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(fpu_686_df_a16)[256] = -{ +const OpFn OP_TABLE(fpu_686_df_a16)[256] = { + // clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -1940,9 +1996,11 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + // clang-format on }; -const OpFn OP_TABLE(fpu_686_df_a32)[256] = -{ + +const OpFn OP_TABLE(fpu_686_df_a32)[256] = { + // clang-format off opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, @@ -1978,10 +2036,11 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + // clang-format on }; -const OpFn OP_TABLE(nofpu_a16)[256] = -{ +const OpFn OP_TABLE(nofpu_a16)[256] = { + // clang-format off op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, @@ -2017,9 +2076,11 @@ const OpFn OP_TABLE(nofpu_a16)[256] = op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + // clang-format on }; -const OpFn OP_TABLE(nofpu_a32)[256] = -{ + +const OpFn OP_TABLE(nofpu_a32)[256] = { + // clang-format off op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, @@ -2055,6 +2116,7 @@ const OpFn OP_TABLE(nofpu_a32)[256] = op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + // clang-format on }; #endif diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index 5e4bfceab..f5e5d7696 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -1,457 +1,508 @@ -#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ -static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ - ST(0) += use_var; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(FE_TONEAREST); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - cpu_state.npxs &= ~(C0|C2|C3); \ - cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - cpu_state.npxs &= ~(C0|C2|C3); \ - cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - x87_pop(); \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), ST(0), use_var); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), use_var, ST(0)); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv ## cycle_postfix) : ((x87_concurrency.fdiv ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) *= use_var; \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul ## cycle_postfix) : ((x87_timings.fmul ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul ## cycle_postfix) : ((x87_concurrency.fmul ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) -= use_var; \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) = use_var - ST(0); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} - +#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ + static int opFADD##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ + ST(0) += use_var; \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(FE_TONEAREST); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFCOM##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFCOMP##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ + x87_pop(); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFDIV##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + x87_div(ST(0), ST(0), use_var); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFDIVR##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + x87_div(ST(0), use_var, ST(0)); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv##cycle_postfix) : ((x87_concurrency.fdiv##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFMUL##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) *= use_var; \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul##cycle_postfix) : ((x87_timings.fmul##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul##cycle_postfix) : ((x87_concurrency.fmul##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFSUB##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) -= use_var; \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFSUBR##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) = use_var - ST(0); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32) #ifndef FPU_8087 -opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) + opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) #endif -opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) + opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) #ifndef FPU_8087 -opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) + opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) #endif -opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16) + opFPU(iw, uint16_t, 16, t, geteaw, (double) (int16_t) t, _i16) #ifndef FPU_8087 -opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16) + opFPU(iw, uint16_t, 32, t, geteaw, (double) (int16_t) t, _i16) #endif -opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32) + opFPU(il, uint32_t, 16, t, geteal, (double) (int32_t) t, _i32) #ifndef FPU_8087 -opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32) + opFPU(il, uint32_t, 32, t, geteal, (double) (int32_t) t, _i32) #endif - -static int opFADD(uint32_t fetchdat) + static int opFADD(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(0) + ST(fetchdat & 7); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) + ST(fetchdat & 7); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFADDr(uint32_t fetchdat) +static int +opFADDr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFADDP(uint32_t fetchdat) +static int +opFADDP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFCOM(uint32_t fetchdat) +static int +opFCOM(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.npxs |= C3; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.npxs |= C0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } -static int opFCOMP(uint32_t fetchdat) +static int +opFCOMP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } -static int opFCOMPP(uint32_t fetchdat) +static int +opFCOMPP(uint32_t fetchdat) { - uint64_t *p, *q; - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - p = (uint64_t *)&ST(0); - q = (uint64_t *)&ST(1); - if ((*p == ((uint64_t)1 << 63) && *q == 0) && (fpu_type >= FPU_287XL)) - cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ - else - cpu_state.npxs |= x87_compare(ST(0), ST(1)); + uint64_t *p, *q; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + p = (uint64_t *) &ST(0); + q = (uint64_t *) &ST(1); + if ((*p == ((uint64_t) 1 << 63) && *q == 0) && (fpu_type >= FPU_287XL)) + cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ + else + cpu_state.npxs |= x87_compare(ST(0), ST(1)); - x87_pop(); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + x87_pop(); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFUCOMPP(uint32_t fetchdat) +static int +opFUCOMPP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); - x87_pop(); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); + x87_pop(); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFCOMI(uint32_t fetchdat) +static int +opFCOMI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } -static int opFCOMIP(uint32_t fetchdat) +static int +opFCOMIP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } #endif -static int opFDIV(uint32_t fetchdat) +static int +opFDIV(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(0), ST(0), ST(fetchdat & 7)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(0), ST(fetchdat & 7)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVr(uint32_t fetchdat) +static int +opFDIVr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVP(uint32_t fetchdat) +static int +opFDIVP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVR(uint32_t fetchdat) +static int +opFDIVR(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(0), ST(fetchdat&7), ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(fetchdat & 7), ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVRr(uint32_t fetchdat) +static int +opFDIVRr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVRP(uint32_t fetchdat) +static int +opFDIVRP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFMUL(uint32_t fetchdat) +static int +opFMUL(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(0) * ST(fetchdat & 7); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) * ST(fetchdat & 7); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); + return 0; } -static int opFMULr(uint32_t fetchdat) +static int +opFMULr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); + return 0; } -static int opFMULP(uint32_t fetchdat) +static int +opFMULP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); + return 0; } -static int opFSUB(uint32_t fetchdat) +static int +opFSUB(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(0) - ST(fetchdat & 7); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) - ST(fetchdat & 7); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBr(uint32_t fetchdat) +static int +opFSUBr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBP(uint32_t fetchdat) +static int +opFSUBP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBR(uint32_t fetchdat) +static int +opFSUBR(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(fetchdat & 7) - ST(0); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(fetchdat & 7) - ST(0); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBRr(uint32_t fetchdat) +static int +opFSUBRr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBRP(uint32_t fetchdat) +static int +opFSUBRP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFUCOM(uint32_t fetchdat) +static int +opFUCOM(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFUCOMP(uint32_t fetchdat) +static int +opFUCOMP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFUCOMI(uint32_t fetchdat) +static int +opFUCOMI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFUCOMIP(uint32_t fetchdat) +static int +opFUCOMIP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } #endif diff --git a/src/cpu/x87_ops_conv.h b/src/cpu/x87_ops_conv.h index 44304c1bc..bb1e497da 100644 --- a/src/cpu/x87_ops_conv.h +++ b/src/cpu/x87_ops_conv.h @@ -4,65 +4,66 @@ typedef struct { int16_t begin; union { - double d; + double d; uint64_t ll; } eind; } x87_conv_t; -static __inline double x87_from80(x87_conv_t *test) +static __inline double +x87_from80(x87_conv_t *test) { - int64_t exp64; - int64_t blah; - int64_t exp64final; - int64_t mant64; - int64_t sign; + int64_t exp64; + int64_t blah; + int64_t exp64final; + int64_t mant64; + int64_t sign; - exp64 = (((test->begin&0x7fff) - BIAS80)); - blah = ((exp64 >0)?exp64:-exp64)&0x3ff; - exp64final = ((exp64 >0)?blah:-blah) +BIAS64; + exp64 = (((test->begin & 0x7fff) - BIAS80)); + blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff; + exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64; - mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll); - sign = (test->begin&0x8000)?1:0; + mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll); + sign = (test->begin & 0x8000) ? 1 : 0; - if ((test->begin & 0x7fff) == 0x7fff) - exp64final = 0x7ff; - if ((test->begin & 0x7fff) == 0) - exp64final = 0; - if (test->eind.ll & 0x400) - mant64++; + if ((test->begin & 0x7fff) == 0x7fff) + exp64final = 0x7ff; + if ((test->begin & 0x7fff) == 0) + exp64final = 0; + if (test->eind.ll & 0x400) + mant64++; - test->eind.ll = (sign <<63)|(exp64final << 52)| mant64; + test->eind.ll = (sign << 63) | (exp64final << 52) | mant64; - return test->eind.d; + return test->eind.d; } -static __inline void x87_to80(double d, x87_conv_t *test) +static __inline void +x87_to80(double d, x87_conv_t *test) { - int64_t sign80; - int64_t exp80; - int64_t exp80final; - int64_t mant80; - int64_t mant80final; + int64_t sign80; + int64_t exp80; + int64_t exp80final; + int64_t mant80; + int64_t mant80final; - test->eind.d=d; + test->eind.d = d; - sign80 = (test->eind.ll&(0x8000000000000000ll))?1:0; - exp80 = test->eind.ll&(0x7ff0000000000000ll); - exp80final = (exp80>>52); - mant80 = test->eind.ll&(0x000fffffffffffffll); - mant80final = (mant80 << 11); + sign80 = (test->eind.ll & (0x8000000000000000ll)) ? 1 : 0; + exp80 = test->eind.ll & (0x7ff0000000000000ll); + exp80final = (exp80 >> 52); + mant80 = test->eind.ll & (0x000fffffffffffffll); + mant80final = (mant80 << 11); - if (exp80final == 0x7ff) /*Infinity / Nan*/ - { - exp80final = 0x7fff; - mant80final |= (0x8000000000000000ll); - } - else if (d != 0){ /* Zero is a special case */ - /* Elvira wants the 8 and tcalc doesn't */ - mant80final |= (0x8000000000000000ll); - /* Ca-cyber doesn't like this when result is zero. */ - exp80final += (BIAS80 - BIAS64); - } - test->begin = (((int16_t)sign80)<<15)| (int16_t)exp80final; - test->eind.ll = mant80final; + if (exp80final == 0x7ff) /*Infinity / Nan*/ + { + exp80final = 0x7fff; + mant80final |= (0x8000000000000000ll); + } else if (d != 0) { /* Zero is a special case */ + /* Elvira wants the 8 and tcalc doesn't */ + mant80final |= (0x8000000000000000ll); + /* Ca-cyber doesn't like this when result is zero. */ + exp80final += (BIAS80 - BIAS64); + } + test->begin = (((int16_t) sign80) << 15) | (int16_t) exp80final; + test->eind.ll = mant80final; } diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index 9afa6815a..8d3c3f700 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -1,510 +1,597 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * x87 FPU instructions core. + * x87 FPU instructions core. * - * Version: @(#)x87_ops_loadstore.h 1.0.2 2019/06/11 * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ -static int opFILDiw_a16(uint32_t fetchdat) +static int +opFILDiw_a16(uint32_t fetchdat) { - int16_t temp; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - x87_push((double)temp); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); - return 0; + int16_t temp; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFILDiw_a32(uint32_t fetchdat) +static int +opFILDiw_a32(uint32_t fetchdat) { - int16_t temp; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - x87_push((double)temp); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); - return 0; + int16_t temp; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); + return 0; } #endif -static int opFISTiw_a16(uint32_t fetchdat) +static int +opFISTiw_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFISTiw_a32(uint32_t fetchdat) +static int +opFISTiw_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFISTPiw_a16(uint32_t fetchdat) +static int +opFISTPiw_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFISTPiw_a32(uint32_t fetchdat) +static int +opFISTPiw_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return 0; } #endif -static int opFILDiq_a16(uint32_t fetchdat) +static int +opFILDiq_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = geteaq(); if (cpu_state.abrt) return 1; - x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP&7].q = temp64; - FP_TAG_DEFAULT; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp64); + cpu_state.MM[cpu_state.TOP & 7].q = temp64; + FP_TAG_DEFAULT; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); - return 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFILDiq_a32(uint32_t fetchdat) +static int +opFILDiq_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = geteaq(); if (cpu_state.abrt) return 1; - x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP&7].q = temp64; - FP_TAG_DEFAULT; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp64); + cpu_state.MM[cpu_state.TOP & 7].q = temp64; + FP_TAG_DEFAULT; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); - return 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; } #endif -static int FBSTP_a16(uint32_t fetchdat) +static int +FBSTP_a16(uint32_t fetchdat) { - double tempd; - int c; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - tempd = ST(0); - if (tempd < 0.0) - tempd = -tempd; - for (c = 0; c < 9; c++) - { - uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - writememb(easeg, cpu_state.eaaddr + c, tempc); - } - tempc = (uint8_t)floor(fmod(tempd, 10.0)); - if (ST(0) < 0.0) tempc |= 0x80; - writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fbstp) : (x87_concurrency.fbstp * cpu_multi)); - return 0; + double tempd; + int c; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) { + uint8_t tempc = (uint8_t) floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t) floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t) floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) + tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fbstp) : (x87_concurrency.fbstp * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int FBSTP_a32(uint32_t fetchdat) +static int +FBSTP_a32(uint32_t fetchdat) { - double tempd; - int c; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - tempd = ST(0); - if (tempd < 0.0) - tempd = -tempd; - for (c = 0; c < 9; c++) - { - uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - writememb(easeg, cpu_state.eaaddr + c, tempc); - } - tempc = (uint8_t)floor(fmod(tempd, 10.0)); - if (ST(0) < 0.0) tempc |= 0x80; - writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); - return 0; + double tempd; + int c; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) { + uint8_t tempc = (uint8_t) floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t) floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t) floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) + tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); + return 0; } #endif -static int FISTPiq_a16(uint32_t fetchdat) +static int +FISTPiq_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP&7].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP & 7].q; + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int FISTPiq_a32(uint32_t fetchdat) +static int +FISTPiq_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP&7].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP & 7].q; + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); + return 0; } #endif -static int opFILDil_a16(uint32_t fetchdat) +static int +opFILDil_a16(uint32_t fetchdat) { - int32_t templ; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)templ); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); - return 0; + int32_t templ; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) templ); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFILDil_a32(uint32_t fetchdat) +static int +opFILDil_a32(uint32_t fetchdat) { - int32_t templ; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)templ); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); - return 0; + int32_t templ; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) templ); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); + return 0; } #endif -static int opFISTil_a16(uint32_t fetchdat) +static int +opFISTil_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFISTil_a32(uint32_t fetchdat) +static int +opFISTil_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFISTPil_a16(uint32_t fetchdat) +static int +opFISTPil_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFISTPil_a32(uint32_t fetchdat) +static int +opFISTPil_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return 0; } #endif -static int opFLDe_a16(uint32_t fetchdat) +static int +opFLDe_a16(uint32_t fetchdat) { - double t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t=x87_ld80(); if (cpu_state.abrt) return 1; - x87_push(t); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + double t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t = x87_ld80(); + if (cpu_state.abrt) + return 1; + x87_push(t); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFLDe_a32(uint32_t fetchdat) +static int +opFLDe_a32(uint32_t fetchdat) { - double t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t=x87_ld80(); if (cpu_state.abrt) return 1; - x87_push(t); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + double t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t = x87_ld80(); + if (cpu_state.abrt) + return 1; + x87_push(t); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #endif -static int opFSTPe_a16(uint32_t fetchdat) +static int +opFSTPe_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - x87_st80(ST(0)); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFSTPe_a32(uint32_t fetchdat) +static int +opFSTPe_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - x87_st80(ST(0)); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #endif -static int opFLDd_a16(uint32_t fetchdat) +static int +opFLDd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t.i = geteaq(); if (cpu_state.abrt) return 1; - x87_push(t.d); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push(t.d); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFLDd_a32(uint32_t fetchdat) +static int +opFLDd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t.i = geteaq(); if (cpu_state.abrt) return 1; - x87_push(t.d); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push(t.d); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); + return 0; } #endif -static int opFSTd_a16(uint32_t fetchdat) +static int +opFSTd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return cpu_state.abrt; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFSTd_a32(uint32_t fetchdat) +static int +opFSTd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return cpu_state.abrt; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFSTPd_a16(uint32_t fetchdat) +static int +opFSTPd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFSTPd_a32(uint32_t fetchdat) +static int +opFSTPd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return 0; } #endif -static int opFLDs_a16(uint32_t fetchdat) +static int +opFLDs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - ts.i = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)ts.s); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) ts.s); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFLDs_a32(uint32_t fetchdat) +static int +opFLDs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - ts.i = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)ts.s); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) ts.s); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #endif -static int opFSTs_a16(uint32_t fetchdat) +static int +opFSTs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return cpu_state.abrt; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFSTs_a32(uint32_t fetchdat) +static int +opFSTs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return cpu_state.abrt; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFSTPs_a16(uint32_t fetchdat) +static int +opFSTPs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFSTPs_a32(uint32_t fetchdat) +static int +opFSTPs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #endif diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index 7e27cc287..091d7cc31 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -1,940 +1,1048 @@ #ifdef FPU_8087 -static int opFI(uint32_t fetchdat) +static int +opFI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxc &= ~0x80; - if (rmdat == 0xe1) - cpu_state.npxc |= 0x80; - wait(3, 0); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxc &= ~0x80; + if (rmdat == 0xe1) + cpu_state.npxc |= 0x80; + wait(3, 0); + return 0; } #else -static int opFSTSW_AX(uint32_t fetchdat) +static int +opFSTSW_AX(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - AX = cpu_state.npxs; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + AX = cpu_state.npxs; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return 0; } #endif - -static int opFNOP(uint32_t fetchdat) +static int +opFNOP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); + return 0; } -static int opFCLEX(uint32_t fetchdat) +static int +opFCLEX(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= 0xff00; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= 0xff00; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); + return 0; } -static int opFINIT(uint32_t fetchdat) +static int +opFINIT(uint32_t fetchdat) { - uint64_t *p; - FP_ENTER(); - cpu_state.pc++; + uint64_t *p; + FP_ENTER(); + cpu_state.pc++; #ifdef FPU_8087 - cpu_state.npxc = 0x3FF; + cpu_state.npxc = 0x3FF; #else - cpu_state.npxc = 0x37F; + cpu_state.npxc = 0x37F; #endif - codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); + cpu_state.npxs = 0; + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - *p = 0; + *p = 0; #else - *p = 0x0303030303030303ll; + *p = 0x0303030303030303ll; #endif - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi)); - CPU_BLOCK_END(); - return 0; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi)); + CPU_BLOCK_END(); + return 0; } - -static int opFFREE(uint32_t fetchdat) +static int +opFFREE(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; + FP_ENTER(); + cpu_state.pc++; #ifdef USE_NEW_DYNAREC - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; #else - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; #endif - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); - return 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); + return 0; } -static int opFFREEP(uint32_t fetchdat) +static int +opFFREEP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); + return 0; } -static int opFST(uint32_t fetchdat) +static int +opFST(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); + return 0; } -static int opFSTP(uint32_t fetchdat) +static int +opFSTP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); + return 0; } - - - -static int FSTOR() +static int +FSTOR(void) { - uint64_t *p; - FP_ENTER(); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - case 0x001: /*16-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); - x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - cpu_state.eaaddr += 14; - break; - case 0x100: /*32-bit real mode*/ - case 0x101: /*32-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); - x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - cpu_state.eaaddr += 28; - break; - } - x87_ld_frstor(0); cpu_state.eaaddr += 10; - x87_ld_frstor(1); cpu_state.eaaddr += 10; - x87_ld_frstor(2); cpu_state.eaaddr += 10; - x87_ld_frstor(3); cpu_state.eaaddr += 10; - x87_ld_frstor(4); cpu_state.eaaddr += 10; - x87_ld_frstor(5); cpu_state.eaaddr += 10; - x87_ld_frstor(6); cpu_state.eaaddr += 10; - x87_ld_frstor(7); + uint64_t *p; + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 2); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 14; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 4); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 28; + break; + } + x87_ld_frstor(0); + cpu_state.eaaddr += 10; + x87_ld_frstor(1); + cpu_state.eaaddr += 10; + x87_ld_frstor(2); + cpu_state.eaaddr += 10; + x87_ld_frstor(3); + cpu_state.eaaddr += 10; + x87_ld_frstor(4); + cpu_state.eaaddr += 10; + x87_ld_frstor(5); + cpu_state.eaaddr += 10; + x87_ld_frstor(6); + cpu_state.eaaddr += 10; + x87_ld_frstor(7); - cpu_state.ismmx = 0; - /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times - something like this is needed*/ - p = (uint64_t *) cpu_state.tag; + cpu_state.ismmx = 0; + /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times + something like this is needed*/ + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && (*p == 0x0101010101010101ull)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ull)) #else - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) - #endif - cpu_state.ismmx = 1; + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && !(*p)) +#endif + cpu_state.ismmx = 1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frstor) : (x87_concurrency.frstor * cpu_multi)); - return cpu_state.abrt; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frstor) : (x87_concurrency.frstor * cpu_multi)); + return cpu_state.abrt; } -static int opFSTOR_a16(uint32_t fetchdat) +static int +opFSTOR_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FSTOR(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFSTOR_a32(uint32_t fetchdat) +static int +opFSTOR_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FSTOR(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; } #endif -static int FSAVE() +static int +FSAVE(void) { - uint64_t *p; + uint64_t *p; - FP_ENTER(); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); + FP_ENTER(); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - cpu_state.eaaddr+=14; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x001: /*16-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); - cpu_state.eaaddr+=14; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x100: /*32-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); - cpu_state.eaaddr+=28; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x101: /*32-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); - cpu_state.eaaddr+=28; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + cpu_state.eaaddr += 14; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 8, x87_pc_seg); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + writememw(easeg, cpu_state.eaaddr + 12, x87_op_seg); + cpu_state.eaaddr += 14; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, (x87_op_off >> 16) << 12); + cpu_state.eaaddr += 28; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememl(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememl(easeg, cpu_state.eaaddr + 16, x87_pc_seg); + writememl(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, x87_op_seg); + cpu_state.eaaddr += 28; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + } + + cpu_state.npxc = 0x37F; + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); + cpu_state.npxs = 0; + p = (uint64_t *) cpu_state.tag; +#ifdef USE_NEW_DYNAREC + *p = 0; +#else + *p = 0x0303030303030303ll; +#endif + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); + return cpu_state.abrt; +} +static int +opFSAVE_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSAVE_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#endif + +static int +opFSTSW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSTSW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return cpu_state.abrt; +} +#endif + +static int +opFLD(uint32_t fetchdat) +{ + int old_tag; + uint64_t old_i64; + + FP_ENTER(); + cpu_state.pc++; + old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + x87_push(ST(fetchdat & 7)); + cpu_state.tag[cpu_state.TOP & 7] = old_tag; + cpu_state.MM[cpu_state.TOP & 7].q = old_i64; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld) : (x87_timings.fld * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld) : (x87_concurrency.fld * cpu_multi)); + return 0; +} + +static int +opFXCH(uint32_t fetchdat) +{ + double td; + uint8_t old_tag; + uint64_t old_i64; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = ST(fetchdat & 7); + ST(fetchdat & 7) = td; + old_tag = cpu_state.tag[cpu_state.TOP & 7]; + cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; + old_i64 = cpu_state.MM[cpu_state.TOP & 7].q; + cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxch) : (x87_concurrency.fxch * cpu_multi)); + return 0; +} + +static int +opFCHS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = -ST(0); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fchs) : (x87_concurrency.fchs * cpu_multi)); + return 0; +} + +static int +opFABS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = fabs(ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fabs) : (x87_concurrency.fabs * cpu_multi)); + return 0; +} + +static int +opFTST(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + if (ST(0) == 0.0) + cpu_state.npxs |= C3; + else if (ST(0) < 0.0) + cpu_state.npxs |= C0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); + return 0; +} + +static int +opFXAM(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C1 | C2 | C3); +#ifdef USE_NEW_DYNAREC + if (cpu_state.tag[cpu_state.TOP & 7] == TAG_EMPTY) + cpu_state.npxs |= (C0 | C3); +#else + if (cpu_state.tag[cpu_state.TOP & 7] == 3) + cpu_state.npxs |= (C0 | C3); +#endif + else if (ST(0) == 0.0) + cpu_state.npxs |= C3; + else + cpu_state.npxs |= C2; + if (ST(0) < 0.0) + cpu_state.npxs |= C1; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxam) : (x87_concurrency.fxam * cpu_multi)); + return 0; +} + +static int +opFLD1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.0); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); + return 0; +} + +static int +opFLDL2T(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.3219280948873623); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDL2E(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.4426950408889634); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDPI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.141592653589793); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDEG2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.3010299956639812); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDLN2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push_u64(0x3fe62e42fefa39f0ull); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDZ(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.0); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); + return 0; +} + +static int +opF2XM1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = pow(2.0, ST(0)) - 1.0; + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.f2xm1) : (x87_concurrency.f2xm1 * cpu_multi)); + return 0; +} + +static int +opFYL2X(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log(ST(0)) / log(2.0)); + FP_TAG_VALID_N; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2x) : (x87_concurrency.fyl2x * cpu_multi)); + return 0; +} + +static int +opFYL2XP1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); + FP_TAG_VALID_N; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2xp1) : (x87_concurrency.fyl2xp1 * cpu_multi)); + return 0; +} + +static int +opFPTAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = tan(ST(0)); + FP_TAG_VALID; + x87_push(1.0); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fptan) : (x87_concurrency.fptan * cpu_multi)); + return 0; +} + +static int +opFPATAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = atan2(ST(1), ST(0)); + FP_TAG_VALID_N; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fpatan) : (x87_concurrency.fpatan * cpu_multi)); + return 0; +} + +static int +opFDECSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; +#else + cpu_state.TOP = (cpu_state.TOP - 1) & 7; +#endif + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); + return 0; +} + +static int +opFINCSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; +#ifdef USE_NEW_DYNAREC + cpu_state.TOP++; +#else + cpu_state.TOP = (cpu_state.TOP + 1) & 7; +#endif + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); + return 0; +} + +static int +opFPREM(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t) (ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double) temp64); + FP_TAG_VALID; + cpu_state.npxs &= ~(C0 | C1 | C2 | C3); + if (temp64 & 4) + cpu_state.npxs |= C0; + if (temp64 & 2) + cpu_state.npxs |= C3; + if (temp64 & 1) + cpu_state.npxs |= C1; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem) : (x87_concurrency.fprem * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +opFPREM1(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t) (ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double) temp64); + FP_TAG_VALID; + cpu_state.npxs &= ~(C0 | C1 | C2 | C3); + if (temp64 & 4) + cpu_state.npxs |= C0; + if (temp64 & 2) + cpu_state.npxs |= C3; + if (temp64 & 1) + cpu_state.npxs |= C1; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem1) : (x87_concurrency.fprem1 * cpu_multi)); + return 0; +} +#endif + +static int +opFSQRT(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sqrt(ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsqrt) : (x87_concurrency.fsqrt * cpu_multi)); + return 0; +} + +#ifndef FPU_8087 +static int +opFSINCOS(uint32_t fetchdat) +{ + double td; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = sin(td); + FP_TAG_VALID; + x87_push(cos(td)); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsincos) : (x87_concurrency.fsincos * cpu_multi)); + return 0; +} +#endif + +static int +opFRNDINT(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = (double) x87_fround(ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); + return 0; +} + +static int +opFSCALE(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t) ST(1); + if (ST(0) != 0.0) + ST(0) = ST(0) * pow(2.0, (double) temp64); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fscale) : (x87_concurrency.fscale * cpu_multi)); + return 0; +} + +#ifndef FPU_8087 +static int +opFSIN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sin(ST(0)); + FP_TAG_VALID; + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); + return 0; +} + +static int +opFCOS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = cos(ST(0)); + FP_TAG_VALID; + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); + return 0; +} +#endif + +static int +FLDENV(void) +{ + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 2); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 4); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldenv) : (x87_concurrency.fldenv * cpu_multi)); + return cpu_state.abrt; +} + +static int +opFLDENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFLDENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#endif + +static int +opFLDCW_a16(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.npxc = tempw; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +opFLDCW_a32(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.npxc = tempw; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); + return 0; +} +#endif + +static int +FSTENV(void) +{ + FP_ENTER(); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); + + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 8, x87_pc_seg); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + writememw(easeg, cpu_state.eaaddr + 12, x87_op_seg); + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, (x87_op_off >> 16) << 12); + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememl(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememl(easeg, cpu_state.eaaddr + 16, x87_pc_seg); + writememl(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, x87_op_seg); + break; + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); + return cpu_state.abrt; +} + +static int +opFSTENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSTENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#endif + +static int +opFSTCW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSTCW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return cpu_state.abrt; +} +#endif + +#ifndef FPU_8087 +# define opFCMOV(condition) \ + static int opFCMOV##condition(uint32_t fetchdat) \ + { \ + FP_ENTER(); \ + cpu_state.pc++; \ + if (cond_##condition) { \ + cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + ST(0) = ST(fetchdat & 7); \ + } \ + CLOCK_CYCLES_FPU(4); \ + return 0; \ } - cpu_state.npxc = 0x37F; - codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; -#ifdef USE_NEW_DYNAREC - *p = 0; -#else - *p = 0x0303030303030303ll; -#endif - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); - return cpu_state.abrt; -} -static int opFSAVE_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSAVE(); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSAVE_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSAVE(); - return cpu_state.abrt; -} -#endif - -static int opFSTSW_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSTSW_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return cpu_state.abrt; -} -#endif - - -static int opFLD(uint32_t fetchdat) -{ - int old_tag; - uint64_t old_i64; - - FP_ENTER(); - cpu_state.pc++; - old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; - old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; - x87_push(ST(fetchdat&7)); - cpu_state.tag[cpu_state.TOP&7] = old_tag; - cpu_state.MM[cpu_state.TOP&7].q = old_i64; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld) : (x87_timings.fld * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld) : (x87_concurrency.fld * cpu_multi)); - return 0; -} - -static int opFXCH(uint32_t fetchdat) -{ - double td; - uint8_t old_tag; - uint64_t old_i64; - FP_ENTER(); - cpu_state.pc++; - td = ST(0); - ST(0) = ST(fetchdat&7); - ST(fetchdat&7) = td; - old_tag = cpu_state.tag[cpu_state.TOP&7]; - cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; - old_i64 = cpu_state.MM[cpu_state.TOP&7].q; - cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; - cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; - - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxch) : (x87_concurrency.fxch * cpu_multi)); - return 0; -} - -static int opFCHS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = -ST(0); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fchs) : (x87_concurrency.fchs * cpu_multi)); - return 0; -} - -static int opFABS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = fabs(ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fabs) : (x87_concurrency.fabs * cpu_multi)); - return 0; -} - -static int opFTST(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - if (ST(0) == 0.0) cpu_state.npxs |= C3; - else if (ST(0) < 0.0) cpu_state.npxs |= C0; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); - return 0; -} - -static int opFXAM(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C1|C2|C3); -#ifdef USE_NEW_DYNAREC - if (cpu_state.tag[cpu_state.TOP&7] == TAG_EMPTY) cpu_state.npxs |= (C0|C3); -#else - if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3); -#endif - else if (ST(0) == 0.0) cpu_state.npxs |= C3; - else cpu_state.npxs |= C2; - if (ST(0) < 0.0) cpu_state.npxs |= C1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxam) : (x87_concurrency.fxam * cpu_multi)); - return 0; -} - -static int opFLD1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(1.0); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); - return 0; -} - -static int opFLDL2T(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(3.3219280948873623); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDL2E(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(1.4426950408889634); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDPI(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(3.141592653589793); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDEG2(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(0.3010299956639812); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDLN2(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push_u64(0x3fe62e42fefa39f0ull); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDZ(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(0.0); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); - return 0; -} - -static int opF2XM1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = pow(2.0, ST(0)) - 1.0; - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.f2xm1) : (x87_concurrency.f2xm1 * cpu_multi)); - return 0; -} - -static int opFYL2X(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(1) = ST(1) * (log(ST(0)) / log(2.0)); - FP_TAG_VALID_N; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2x) : (x87_concurrency.fyl2x * cpu_multi)); - return 0; -} - -static int opFYL2XP1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); - FP_TAG_VALID_N; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2xp1) : (x87_concurrency.fyl2xp1 * cpu_multi)); - return 0; -} - -static int opFPTAN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = tan(ST(0)); - FP_TAG_VALID; - x87_push(1.0); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fptan) : (x87_concurrency.fptan * cpu_multi)); - return 0; -} - -static int opFPATAN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(1) = atan2(ST(1), ST(0)); - FP_TAG_VALID_N; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fpatan) : (x87_concurrency.fpatan * cpu_multi)); - return 0; -} - -static int opFDECSTP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; -#ifdef USE_NEW_DYNAREC - cpu_state.TOP--; -#else - cpu_state.TOP = (cpu_state.TOP - 1) & 7; -#endif - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); - return 0; -} - -static int opFINCSTP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; -#ifdef USE_NEW_DYNAREC - cpu_state.TOP++; -#else - cpu_state.TOP = (cpu_state.TOP + 1) & 7; -#endif - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); - return 0; -} - -static int opFPREM(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - temp64 = (int64_t)(ST(0) / ST(1)); - ST(0) = ST(0) - (ST(1) * (double)temp64); - FP_TAG_VALID; - cpu_state.npxs &= ~(C0|C1|C2|C3); - if (temp64 & 4) cpu_state.npxs|=C0; - if (temp64 & 2) cpu_state.npxs|=C3; - if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem) : (x87_concurrency.fprem * cpu_multi)); - return 0; -} -#ifndef FPU_8087 -static int opFPREM1(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - temp64 = (int64_t)(ST(0) / ST(1)); - ST(0) = ST(0) - (ST(1) * (double)temp64); - FP_TAG_VALID; - cpu_state.npxs &= ~(C0|C1|C2|C3); - if (temp64 & 4) cpu_state.npxs|=C0; - if (temp64 & 2) cpu_state.npxs|=C3; - if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem1) : (x87_concurrency.fprem1 * cpu_multi)); - return 0; -} -#endif - -static int opFSQRT(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = sqrt(ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsqrt) : (x87_concurrency.fsqrt * cpu_multi)); - return 0; -} - -#ifndef FPU_8087 -static int opFSINCOS(uint32_t fetchdat) -{ - double td; - FP_ENTER(); - cpu_state.pc++; - td = ST(0); - ST(0) = sin(td); - FP_TAG_VALID; - x87_push(cos(td)); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsincos) : (x87_concurrency.fsincos * cpu_multi)); - return 0; -} -#endif - -static int opFRNDINT(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = (double)x87_fround(ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); - return 0; -} - -static int opFSCALE(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - temp64 = (int64_t)ST(1); - if(ST(0) != 0.0) - ST(0) = ST(0) * pow(2.0, (double)temp64); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fscale) : (x87_concurrency.fscale * cpu_multi)); - return 0; -} - -#ifndef FPU_8087 -static int opFSIN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = sin(ST(0)); - FP_TAG_VALID; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); - return 0; -} - -static int opFCOS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = cos(ST(0)); - FP_TAG_VALID; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); - return 0; -} -#endif - - -static int FLDENV() -{ - FP_ENTER(); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - case 0x001: /*16-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); - x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - break; - case 0x100: /*32-bit real mode*/ - case 0x101: /*32-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); - x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - break; - } - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldenv) : (x87_concurrency.fldenv * cpu_multi)); - return cpu_state.abrt; -} - -static int opFLDENV_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FLDENV(); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFLDENV_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FLDENV(); - return cpu_state.abrt; -} -#endif - -static int opFLDCW_a16(uint32_t fetchdat) -{ - uint16_t tempw; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.npxc = tempw; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); - return 0; -} -#ifndef FPU_8087 -static int opFLDCW_a32(uint32_t fetchdat) -{ - uint16_t tempw; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.npxc = tempw; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); - return 0; -} -#endif - -static int FSTENV() -{ - FP_ENTER(); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); - - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - break; - case 0x001: /*16-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); - break; - case 0x100: /*32-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); - break; - case 0x101: /*32-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); - break; - } - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); - return cpu_state.abrt; -} - -static int opFSTENV_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSTENV(); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSTENV_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSTENV(); - return cpu_state.abrt; -} -#endif - -static int opFSTCW_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.npxc); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSTCW_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.npxc); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return cpu_state.abrt; -} -#endif - -#ifndef FPU_8087 -#define opFCMOV(condition) \ - static int opFCMOV ## condition(uint32_t fetchdat) \ - { \ - FP_ENTER(); \ - cpu_state.pc++; \ - if (cond_ ## condition) \ - { \ - cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ - ST(0) = ST(fetchdat & 7); \ - } \ - CLOCK_CYCLES_FPU(4); \ - return 0; \ - } - -#define cond_U ( PF_SET()) -#define cond_NU (!PF_SET()) +# define cond_U (PF_SET()) +# define cond_NU (!PF_SET()) +// clang-format off opFCMOV(B) opFCMOV(E) opFCMOV(BE) @@ -943,4 +1051,5 @@ opFCMOV(NB) opFCMOV(NE) opFCMOV(NBE) opFCMOV(NU) +// clang-format on #endif diff --git a/src/cpu/x87_timings.c b/src/cpu/x87_timings.c index 70ec4b95e..a23e195d2 100644 --- a/src/cpu/x87_timings.c +++ b/src/cpu/x87_timings.c @@ -85,80 +85,79 @@ const x87_timings_t x87_timings_8087 = { .fyl2xp1 = (700 + 1000) / 2 }; -const x87_timings_t x87_timings_80187 = -{ - .f2xm1 = (310 + 630) / 2, - .fabs = (10 + 17) / 2, - .fadd = (70 + 100) / 2, - .fadd_32 = (90 + 120) / 2, - .fadd_64 = (95 + 125) / 2, - .fbld = (290 + 310) / 2, - .fbstp = (520 + 540) / 2, - .fchs = (10 + 17) / 2, - .fclex = (2 + 8) / 2, - .fcom = (40 + 50) / 2, - .fcom_32 = (60 + 70) / 2, - .fcom_64 = (65 + 75) / 2, - .fcos = 0, /*387+*/ - .fincdecstp = (6 + 12) / 2, - .fdisi_eni = (6 + 12) / 2, - .fdiv = (193 + 203) / 2, - .fdiv_32 = (215 + 225) / 2, - .fdiv_64 = (220 + 230) / 2, - .ffree = (9 + 16) / 2, - .fadd_i16 = (102 + 137) / 2, - .fadd_i32 = (108 + 143) / 2, - .fcom_i16 = (72 + 86) / 2, - .fcom_i32 = (78 + 91) / 2, - .fdiv_i16 = (224 + 238) / 2, - .fdiv_i32 = (230 + 243) / 2, - .fild_16 = (46 + 54) / 2, - .fild_32 = (50 + 60) / 2, - .fild_64 = (60 + 68) / 2, - .fmul_i16 = (124 + 138) / 2, - .fmul_i32 = (130 + 144) / 2, - .finit = (2 + 8) / 2, - .fist_16 = (80 + 90) / 2, - .fist_32 = (82 + 92) / 2, - .fist_64 = (94 + 105) / 2, - .fld = (17 + 22) / 2, - .fld_32 = (38 + 56) / 2, - .fld_64 = (40 + 60) / 2, - .fld_80 = (53 + 65) / 2, - .fld_z1 = (11 + 21) / 2, - .fld_const = (15 + 24) / 2, - .fldcw = (7 + 14) / 2, - .fldenv = (35 + 45) / 2, - .fmul = (90 + 145) / 2, - .fmul_32 = (110 + 125) / 2, - .fmul_64 = (154 + 168) / 2, - .fnop = (10 + 16) / 2, - .fpatan = (250 + 800) / 2, - .fprem = (15 + 190) / 2, - .fprem1 = 0, /*387+*/ - .fptan = (30 + 540) / 2, - .frndint = (16 + 50) / 2, - .frstor = (197 + 207) / 2, - .fsave = (197 + 207) / 2, - .fscale = (32 + 38) / 2, - .fsetpm = 0, /*287+*/ - .fsin_cos = 0, /*387+*/ - .fsincos = 0, /*387+*/ - .fsqrt = (180 + 186) / 2, - .fst = (15 + 22) / 2, - .fst_32 = (84 + 90) / 2, - .fst_64 = (96 + 104) / 2, - .fst_80 = (52 + 58) / 2, - .fstcw_sw = (12 + 18) / 2, - .fstenv = (40 + 50) / 2, - .ftst = (38 + 48) / 2, - .fucom = 0, /*387+*/ - .fwait = 4, - .fxam = (12 + 23) / 2, - .fxch = (10 + 15) / 2, - .fxtract = (27 + 55) / 2, - .fyl2x = (900 + 1100) / 2, - .fyl2xp1 = (700 + 1000) / 2 +const x87_timings_t x87_timings_80187 = { + .f2xm1 = (310 + 630) / 2, + .fabs = (10 + 17) / 2, + .fadd = (70 + 100) / 2, + .fadd_32 = (90 + 120) / 2, + .fadd_64 = (95 + 125) / 2, + .fbld = (290 + 310) / 2, + .fbstp = (520 + 540) / 2, + .fchs = (10 + 17) / 2, + .fclex = (2 + 8) / 2, + .fcom = (40 + 50) / 2, + .fcom_32 = (60 + 70) / 2, + .fcom_64 = (65 + 75) / 2, + .fcos = 0, /*387+*/ + .fincdecstp = (6 + 12) / 2, + .fdisi_eni = (6 + 12) / 2, + .fdiv = (193 + 203) / 2, + .fdiv_32 = (215 + 225) / 2, + .fdiv_64 = (220 + 230) / 2, + .ffree = (9 + 16) / 2, + .fadd_i16 = (102 + 137) / 2, + .fadd_i32 = (108 + 143) / 2, + .fcom_i16 = (72 + 86) / 2, + .fcom_i32 = (78 + 91) / 2, + .fdiv_i16 = (224 + 238) / 2, + .fdiv_i32 = (230 + 243) / 2, + .fild_16 = (46 + 54) / 2, + .fild_32 = (50 + 60) / 2, + .fild_64 = (60 + 68) / 2, + .fmul_i16 = (124 + 138) / 2, + .fmul_i32 = (130 + 144) / 2, + .finit = (2 + 8) / 2, + .fist_16 = (80 + 90) / 2, + .fist_32 = (82 + 92) / 2, + .fist_64 = (94 + 105) / 2, + .fld = (17 + 22) / 2, + .fld_32 = (38 + 56) / 2, + .fld_64 = (40 + 60) / 2, + .fld_80 = (53 + 65) / 2, + .fld_z1 = (11 + 21) / 2, + .fld_const = (15 + 24) / 2, + .fldcw = (7 + 14) / 2, + .fldenv = (35 + 45) / 2, + .fmul = (90 + 145) / 2, + .fmul_32 = (110 + 125) / 2, + .fmul_64 = (154 + 168) / 2, + .fnop = (10 + 16) / 2, + .fpatan = (250 + 800) / 2, + .fprem = (15 + 190) / 2, + .fprem1 = 0, /*387+*/ + .fptan = (30 + 540) / 2, + .frndint = (16 + 50) / 2, + .frstor = (197 + 207) / 2, + .fsave = (197 + 207) / 2, + .fscale = (32 + 38) / 2, + .fsetpm = 0, /*287+*/ + .fsin_cos = 0, /*387+*/ + .fsincos = 0, /*387+*/ + .fsqrt = (180 + 186) / 2, + .fst = (15 + 22) / 2, + .fst_32 = (84 + 90) / 2, + .fst_64 = (96 + 104) / 2, + .fst_80 = (52 + 58) / 2, + .fstcw_sw = (12 + 18) / 2, + .fstenv = (40 + 50) / 2, + .ftst = (38 + 48) / 2, + .fucom = 0, /*387+*/ + .fwait = 4, + .fxam = (12 + 23) / 2, + .fxch = (10 + 15) / 2, + .fxtract = (27 + 55) / 2, + .fyl2x = (900 + 1100) / 2, + .fyl2xp1 = (700 + 1000) / 2 }; /*Mostly the same as 8087*/ diff --git a/src/ddma.c b/src/ddma.c index 88afe3f69..7904163da 100644 --- a/src/ddma.c +++ b/src/ddma.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Distributed DMA emulation. + * Distributed DMA emulation. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020 Miran Grca. */ #include #include diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 658da7280..7fd0b20d0 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c diff --git a/src/device/bugger.c b/src/device/bugger.c index d346f2bd7..920fc4cef 100644 --- a/src/device/bugger.c +++ b/src/device/bugger.c @@ -1,53 +1,53 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the ISA Bus (de)Bugger expansion card - * sold as a DIY kit in the late 1980's in The Netherlands. - * This card was a assemble-yourself 8bit ISA addon card for - * PC and AT systems that had several tools to aid in low- - * level debugging (mostly for faulty BIOSes, bootloaders - * and system kernels...) + * Implementation of the ISA Bus (de)Bugger expansion card + * sold as a DIY kit in the late 1980's in The Netherlands. + * This card was a assemble-yourself 8bit ISA addon card for + * PC and AT systems that had several tools to aid in low- + * level debugging (mostly for faulty BIOSes, bootloaders + * and system kernels...) * - * The standard version had a total of 16 LEDs (8 RED, plus - * 8 GREEN), two 7-segment displays and one 8-position DIP - * switch block on board for use as debugging tools. + * The standard version had a total of 16 LEDs (8 RED, plus + * 8 GREEN), two 7-segment displays and one 8-position DIP + * switch block on board for use as debugging tools. * - * The "Plus" version, added an extra 2 7-segment displays, - * as well as a very simple RS-232 serial interface that - * could be used as a mini-console terminal. + * The "Plus" version, added an extra 2 7-segment displays, + * as well as a very simple RS-232 serial interface that + * could be used as a mini-console terminal. * - * Two I/O ports were used; one for control, at offset 0 in - * I/O space, and one for data, at offset 1 in I/O space. - * Both registers could be read from and written to. Although - * the author has a vague memory of a DIP switch to set the - * board's I/O address, comments in old software seems to - * indicate that it was actually fixed to 0x7A (and 0x7B.) + * Two I/O ports were used; one for control, at offset 0 in + * I/O space, and one for data, at offset 1 in I/O space. + * Both registers could be read from and written to. Although + * the author has a vague memory of a DIP switch to set the + * board's I/O address, comments in old software seems to + * indicate that it was actually fixed to 0x7A (and 0x7B.) * - * A READ on the data register always returned the actual - * state of the DIP switch. Writing data to the LEDs was done - * in two steps.. first, the block number (RED or GREEN) was - * written to the CTRL register, and then the actual LED data - * was written to the DATA register. Likewise, data for the - * 7-segment displays was written. + * A READ on the data register always returned the actual + * state of the DIP switch. Writing data to the LEDs was done + * in two steps.. first, the block number (RED or GREEN) was + * written to the CTRL register, and then the actual LED data + * was written to the DATA register. Likewise, data for the + * 7-segment displays was written. * - * The serial port was a bit different, and its operation is - * not verified, but two extra bits in the control register - * were used to set up parameters, and also the actual data - * input and output. + * The serial port was a bit different, and its operation is + * not verified, but two extra bits in the control register + * were used to set up parameters, and also the actual data + * input and output. * - * TODO: Still have to implement the RS232 Serial Port Parameters - * configuration register (CTRL_SPCFG bit set) but have to - * remember that stuff first... + * TODO: Still have to implement the RS232 Serial Port Parameters + * configuration register (CTRL_SPCFG bit set) but have to + * remember that stuff first... * * * - * Author: Fred N. van Kempen, - * Copyright 1989-2018 Fred N. van Kempen. + * Authors: Fred N. van Kempen, + * Copyright 1989-2018 Fred N. van Kempen. */ #include #include diff --git a/src/device/cartridge.c b/src/device/cartridge.c index ea043e0f4..943ca2cb9 100644 --- a/src/device/cartridge.c +++ b/src/device/cartridge.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the PCjr cartridge emulation. + * Implementation of the PCjr cartridge emulation. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2021 Miran Grca. + * Copyright 2021 Miran Grca. */ #include #include diff --git a/src/device/clock_ics9xxx.c b/src/device/clock_ics9xxx.c index 47d1301ee..7b04c5688 100644 --- a/src/device/clock_ics9xxx.c +++ b/src/device/clock_ics9xxx.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the ICS9xxx series of clock generators. + * Emulation of the ICS9xxx series of clock generators. * * * - * Authors: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include diff --git a/src/device/hasp.c b/src/device/hasp.c index 7d7d92a53..8c71e1f3f 100644 --- a/src/device/hasp.c +++ b/src/device/hasp.c @@ -1,24 +1,24 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * HASP parallel port copy protection dongle emulation. + * HASP parallel port copy protection dongle emulation. * - * Based on the MAME driver for Savage Quest. This incomplete - * emulation is enough to satisfy that game, but not Aladdin's - * DiagnostiX utility. + * Based on the MAME driver for Savage Quest. This incomplete + * emulation is enough to satisfy that game, but not Aladdin's + * DiagnostiX utility. * * * - * Author: RichardG, - * Peter Ferrie + * Authors: RichardG, + * Peter Ferrie * - * Copyright 2021 RichardG. - * Copyright Peter Ferrie. + * Copyright 2021 RichardG. + * Copyright Peter Ferrie. */ #include #include diff --git a/src/device/hwm.c b/src/device/hwm.c index 5d9950285..85c689740 100644 --- a/src/device/hwm.c +++ b/src/device/hwm.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Common functions for hardware monitoring chips. + * Common functions for hardware monitoring chips. * * * - * Author: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include @@ -31,7 +31,7 @@ hwm_values_t hwm_values; uint16_t -hwm_get_vcore() +hwm_get_vcore(void) { /* Determine Vcore for the active CPU. */ return cpu_s->voltage; diff --git a/src/device/hwm_gl518sm.c b/src/device/hwm_gl518sm.c index 99318ae6f..730e2f2ce 100644 --- a/src/device/hwm_gl518sm.c +++ b/src/device/hwm_gl518sm.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the Genesys Logic GL518SM hardware monitoring chip. + * Emulation of the Genesys Logic GL518SM hardware monitoring chip. * * * - * Author: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include @@ -279,8 +279,8 @@ gl518sm_init(const device_t *info) }, { /* voltages */ - hwm_get_vcore(), /* Vcore */ - RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the datasheet) */ + hwm_get_vcore(), /* Vcore */ + RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the datasheet) */ 3300, /* +3.3V */ 5000 /* +5V */ } diff --git a/src/device/hwm_lm75.c b/src/device/hwm_lm75.c index bf0c0a77a..fdfff0e44 100644 --- a/src/device/hwm_lm75.c +++ b/src/device/hwm_lm75.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the National Semiconductor LM75 temperature sensor chip. + * Emulation of the National Semiconductor LM75 temperature sensor chip. * * * - * Author: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index f446053d7..f7585945a 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the National Semiconductor LM78 hardware monitoring chip. + * Emulation of the National Semiconductor LM78 hardware monitoring chip. * * * - * Author: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include @@ -757,25 +757,25 @@ lm78_init(const device_t *info) hwm_values_t defaults = { { /* fan speeds */ - 3000, /* usually Chassis, sometimes CPU */ + 3000, /* usually Chassis, sometimes CPU */ 3000, /* usually CPU, sometimes Chassis */ 3000 /* usually PSU, sometimes Chassis */ }, { /* temperatures */ - 30, /* usually Board, sometimes Chassis */ - 30, /* Winbond only: usually CPU, sometimes Probe */ + 30, /* usually Board, sometimes Chassis */ + 30, /* Winbond only: usually CPU, sometimes Probe */ 30 /* Winbond only: usually CPU when not the one above */ }, { /* voltages */ - hwm_get_vcore(), /* Vcore */ - 0, /* sometimes Vtt, Vio or second CPU */ - 3300, /* +3.3V */ - RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ + hwm_get_vcore(), /* Vcore */ + 0, /* sometimes Vtt, Vio or second CPU */ + 3300, /* +3.3V */ + RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ - LM78_NEG_VOLTAGE(12000, 2100), /* -12V */ - LM78_NEG_VOLTAGE(5000, 909), /* -5V */ + LM78_NEG_VOLTAGE(12000, 2100), /* -12V */ + LM78_NEG_VOLTAGE(5000, 909), /* -5V */ RESISTOR_DIVIDER(5000, 51, 75), /* W83782D/AS99127F only: +5VSB (5.1K/7.5K divider suggested in the datasheet) */ 3000, /* W83782D/AS99127F only: Vbat */ 2500, /* AS99127F only: +2.5V */ diff --git a/src/device/hwm_vt82c686.c b/src/device/hwm_vt82c686.c index 88603e10a..877138a4a 100644 --- a/src/device/hwm_vt82c686.c +++ b/src/device/hwm_vt82c686.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the VIA VT82C686A/B integrated hardware monitor. + * Emulation of the VIA VT82C686A/B integrated hardware monitor. * * * - * Author: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include @@ -182,7 +182,7 @@ vt82c686_init(const device_t *info) /* Set default values. Since this hardware monitor has a complex voltage factor system, the values struct contains voltage values *before* applying their respective factors. */ hwm_values_t defaults = { -// clang-format on + // clang-format off { /* fan speeds */ 3000, /* usually CPU */ 3000 /* usually Chassis */ @@ -197,7 +197,7 @@ vt82c686_init(const device_t *info) 5000, /* +5V */ 12000 /* +12V */ } -// clang-format on + // clang-format on }; hwm_values = defaults; dev->values = &hwm_values; diff --git a/src/device/i2c.c b/src/device/i2c.c index 79586a9ed..17e795e74 100644 --- a/src/device/i2c.c +++ b/src/device/i2c.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the I2C bus and its operations. + * Implementation of the I2C bus and its operations. * * * - * Authors: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include diff --git a/src/device/i2c_gpio.c b/src/device/i2c_gpio.c index e2af6d1de..cb7cf6147 100644 --- a/src/device/i2c_gpio.c +++ b/src/device/i2c_gpio.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of a GPIO-based I2C host controller. + * Emulation of a GPIO-based I2C host controller. * * * - * Authors: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include diff --git a/src/device/ibm_5161.c b/src/device/ibm_5161.c index d2ba5cac0..ea62c2abf 100644 --- a/src/device/ibm_5161.c +++ b/src/device/ibm_5161.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of the IBM Expansion Unit (5161). + * Emulation of the IBM Expansion Unit (5161). * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2018 Miran Grca. */ #include #include diff --git a/src/device/isamem.c b/src/device/isamem.c index 839f37f92..52327ad2c 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -1614,6 +1614,6 @@ isamem_get_from_internal_name(const char *s) const device_t * isamem_get_device(int board) { -/* Add the instance to the system. */ + /* Add the instance to the system. */ return boards[board].dev; } diff --git a/src/device/isapnp.c b/src/device/isapnp.c index b2392b6a3..69d5e26ab 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of ISA Plug and Play. + * Implementation of ISA Plug and Play. * * * - * Author: Miran Grca, - * RichardG, + * Authors: Miran Grca, + * RichardG, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2021 RichardG. + * Copyright 2016-2018 Miran Grca. + * Copyright 2021 RichardG. */ #include #include diff --git a/src/device/isartc.c b/src/device/isartc.c index 66accb66a..ad2b39f2f 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -763,7 +763,7 @@ isartc_get_from_internal_name(char *s) c++; } -/* Not found. */ + /* Not found. */ return (0); } diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 7d35d41cb..a5503cc3b 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * General keyboard driver interface. + * General keyboard driver interface. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2015-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2015-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include @@ -34,7 +34,7 @@ void (*keyboard_send)(uint16_t val); static int recv_key[512]; /* keyboard input buffer */ static int oldkey[512]; #if 0 -static int keydelay[512]; +static int keydelay[512]; #endif static scancode *scan_table; /* scancode table for keyboard */ diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index dc282e8a6..f6d02a4d4 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -1,24 +1,24 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the XT-style keyboard. + * Implementation of the XT-style keyboard. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * EngiNerd, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * EngiNerd, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van kempen. - * Copyright 2020 EngiNerd. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van kempen. + * Copyright 2020 EngiNerd. */ #include #include @@ -367,7 +367,7 @@ kbd_log(const char *fmt, ...) #endif static uint8_t -get_fdd_switch_settings() +get_fdd_switch_settings(void) { int i, fdd_count = 0; @@ -384,7 +384,7 @@ get_fdd_switch_settings() } static uint8_t -get_videomode_switch_settings() +get_videomode_switch_settings(void) { if (video_is_mda()) @@ -411,7 +411,7 @@ kbd_poll(void *priv) kbd->blocked = 1; picint(2); #ifdef ENABLE_KEYBOARD_XT_LOG - kbd_log("kbd_poll(): keyboard_xt : take IRQ\n"); + kbd_log("XTkbd: kbd_poll(): keyboard_xt : take IRQ\n"); #endif } @@ -430,7 +430,7 @@ kbd_adddata(uint16_t val) /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ if (is_t1x00) { if (keyboard_recv(0x138) || keyboard_recv(0x11d)) { /* 'Fn' pressed */ - t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */ + t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */ switch (val) { case 0x45: /* Num Lock => toggle numpad */ t1000_syskey(0x00, 0x00, 0x10); @@ -515,7 +515,7 @@ static void kbd_write(uint16_t port, uint8_t val, void *priv) { xtkbd_t *kbd = (xtkbd_t *) priv; - uint8_t bit, set, new_clock; + uint8_t bit, set, new_clock; switch (port) { case 0x61: /* Keyboard Control Register (aka Port B) */ @@ -531,7 +531,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) kbd->pb = val; if (!(kbd->pb & 0x80)) kbd->clock = !!(kbd->pb & 0x40); - ppi.pb = val; + ppi.pb = val; timer_process(); @@ -556,21 +556,21 @@ kbd_write(uint16_t port, uint8_t val, void *priv) #ifdef ENABLE_KEYBOARD_XT_LOG if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) - kbd_log("Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF"); + kbd_log("XTkbd: Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF"); #endif break; #ifdef ENABLE_KEYBOARD_XT_LOG case 0x62: /* Switch Register (aka Port C) */ if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) - kbd_log("Cassette IN is %i\n", !!(val & 0x10)); + kbd_log("XTkbd: Cassette IN is %i\n", !!(val & 0x10)); break; #endif case 0xc0 ... 0xcf: /* Pravetz Flags */ - kbd_log("Port %02X out: %02X\n", port, val); + kbd_log("XTkbd: Port %02X out: %02X\n", port, val); if (kbd->type == KBD_TYPE_PRAVETZ) { - bit = (port >> 1) & 0x07; - set = (port & 0x01) << bit; + bit = (port >> 1) & 0x07; + set = (port & 0x01) << bit; kbd->pravetz_flags = (kbd->pravetz_flags & ~(1 << bit)) | set; } break; @@ -680,7 +680,7 @@ kbd_read(uint16_t port, void *priv) case 0xc0: /* Pravetz Flags */ if (kbd->type == KBD_TYPE_PRAVETZ) ret = kbd->pravetz_flags; - kbd_log("Port %02X in : %02X\n", port, ret); + kbd_log("XTkbd: Port %02X in : %02X\n", port, ret); break; } @@ -692,10 +692,10 @@ kbd_reset(void *priv) { xtkbd_t *kbd = (xtkbd_t *) priv; - kbd->want_irq = 0; - kbd->blocked = 0; - kbd->pa = 0x00; - kbd->pb = 0x00; + kbd->want_irq = 0; + kbd->blocked = 0; + kbd->pa = 0x00; + kbd->pb = 0x00; kbd->pravetz_flags = 0x00; keyboard_scan = 1; diff --git a/src/device/mouse.c b/src/device/mouse.c index 7e14129bb..422161a83 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Common driver module for MOUSE devices. + * Common driver module for MOUSE devices. * - * TODO: Add the Genius bus- and serial mouse. - * Remove the '3-button' flag from mouse types. + * TODO: Add the Genius bus- and serial mouse. + * Remove the '3-button' flag from mouse types. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017-2018 Fred N. van Kempen. */ #include #include @@ -87,7 +87,7 @@ static mouse_t mouse_devices[] = { static const device_t *mouse_curr; static void *mouse_priv; static int mouse_nbut; -static int (*mouse_dev_poll)(); +static int (*mouse_dev_poll)(int x, int y, int z, int b, void *priv); #ifdef ENABLE_MOUSE_LOG int mouse_do_log = ENABLE_MOUSE_LOG; diff --git a/src/device/mouse_bus.c b/src/device/mouse_bus.c index cc9f6ecca..802ae6d45 100644 --- a/src/device/mouse_bus.c +++ b/src/device/mouse_bus.c @@ -1,70 +1,70 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Bus Mouse devices. + * Implementation of Bus Mouse devices. * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. + * These devices were made by both Microsoft and Logitech. At + * first, Microsoft used the same protocol as Logitech, but did + * switch to their new protocol for their InPort interface. So, + * although alike enough to be handled in the same driver, they + * are not the same. * - * NOTES: Ported from Bochs with extensive modifications per testing - * of the real hardware, testing of drivers, and the old code. + * NOTES: Ported from Bochs with extensive modifications per testing + * of the real hardware, testing of drivers, and the old code. * - * Logitech Bus Mouse verified with: - * Linux Slackware 3.0 - * Logitech LMouse.com 3.12 - * Logitech LMouse.com 3.30 - * Logitech LMouse.com 3.41 - * Logitech LMouse.com 3.42 - * Logitech LMouse.com 4.00 - * Logitech LMouse.com 5.00 - * Logitech LMouse.com 6.00 - * Logitech LMouse.com 6.02 Beta - * Logitech LMouse.com 6.02 - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.20 - * Logitech LMouse.com 6.23 - * Logitech LMouse.com 6.30 - * Logitech LMouse.com 6.31E - * Logitech LMouse.com 6.34 - * Logitech Mouse.exe 6.40 - * Logitech Mouse.exe 6.41 - * Logitech Mouse.exe 6.44 - * Logitech Mouse.exe 6.46 - * Logitech Mouse.exe 6.50 - * Microsoft Mouse.com 2.00 - * Microsoft Mouse.sys 3.00 - * Microsoft Mouse.com 7.04 - * Microsoft Mouse.com 8.21J - * Microsoft Windows 1.00 DR5 - * Microsoft Windows 3.10.026 - * Microsoft Windows 3.10.068 both MOUSE.DRV and LMOUSE.DRV - * Microsoft Windows NT 3.1 - * Microsoft Windows 95 + * Logitech Bus Mouse verified with: + * Linux Slackware 3.0 + * Logitech LMouse.com 3.12 + * Logitech LMouse.com 3.30 + * Logitech LMouse.com 3.41 + * Logitech LMouse.com 3.42 + * Logitech LMouse.com 4.00 + * Logitech LMouse.com 5.00 + * Logitech LMouse.com 6.00 + * Logitech LMouse.com 6.02 Beta + * Logitech LMouse.com 6.02 + * Logitech LMouse.com 6.12 + * Logitech LMouse.com 6.20 + * Logitech LMouse.com 6.23 + * Logitech LMouse.com 6.30 + * Logitech LMouse.com 6.31E + * Logitech LMouse.com 6.34 + * Logitech Mouse.exe 6.40 + * Logitech Mouse.exe 6.41 + * Logitech Mouse.exe 6.44 + * Logitech Mouse.exe 6.46 + * Logitech Mouse.exe 6.50 + * Microsoft Mouse.com 2.00 + * Microsoft Mouse.sys 3.00 + * Microsoft Mouse.com 7.04 + * Microsoft Mouse.com 8.21J + * Microsoft Windows 1.00 DR5 + * Microsoft Windows 3.10.026 + * Microsoft Windows 3.10.068 both MOUSE.DRV and LMOUSE.DRV + * Microsoft Windows NT 3.1 + * Microsoft Windows 95 * - * InPort verified with: - * Linux Slackware 3.0 - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.41 - * Microsoft Windows 3.10.068 both MOUSE.DRV and LMOUSE.DRV - * Microsoft Windows NT 3.1 - * Microsoft Windows 98 SE + * InPort verified with: + * Linux Slackware 3.0 + * Logitech LMouse.com 6.12 + * Logitech LMouse.com 6.41 + * Microsoft Windows 3.10.068 both MOUSE.DRV and LMOUSE.DRV + * Microsoft Windows NT 3.1 + * Microsoft Windows 98 SE * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 200?-2019 Bochs. - * Copyright 2017-2019 Miran Grca. - * Copyright 1989-2019 Fred N. van Kempen. + * Copyright 200?-2019 Bochs. + * Copyright 2017-2019 Miran Grca. + * Copyright 1989-2019 Fred N. van Kempen. */ #include #include @@ -800,7 +800,7 @@ static const device_config_t ms_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mouse_logibus_device = { diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 39390db02..e7670b2fc 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of PS/2 series Mouse devices. + * Implementation of PS/2 series Mouse devices. * * * - * Authors: Fred N. van Kempen, + * Authors: Fred N. van Kempen, */ #include #include @@ -37,8 +37,8 @@ typedef struct { int mode; uint16_t flags; - uint8_t resolution; - uint8_t sample_rate; + uint8_t resolution; + uint8_t sample_rate; uint8_t command; @@ -84,7 +84,7 @@ mouse_clear_data(void *priv) static void ps2_report_coordinates(mouse_t *dev) { - uint8_t buff[3] = {0x08, 0x00, 0x00}; + uint8_t buff[3] = { 0x08, 0x00, 0x00 }; if (dev->x > 255) dev->x = 255; @@ -248,14 +248,13 @@ mouse_reset: dev->last_data[5] = val; if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 - && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0xc8 - && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50 - && mouse_get_buttons() == 5) { + && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0xc8 + && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50 + && mouse_get_buttons() == 5) { dev->flags |= FLAG_INTMODE | FLAG_5BTN; - } - else if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 - && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0x64 - && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50) { + } else if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 + && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0x64 + && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50) { dev->flags |= FLAG_INTMODE; } } @@ -264,7 +263,7 @@ mouse_reset: static int ps2_poll(int x, int y, int z, int b, void *priv) { - mouse_t *dev = (mouse_t *) priv; + mouse_t *dev = (mouse_t *) priv; if (!x && !y && !z && (b == dev->b)) return (0xff); @@ -310,7 +309,8 @@ mouse_ps2_init(const device_t *info) if (i > 2) dev->flags |= FLAG_INTELLI; - if (i == 4) i = 3; + if (i == 4) + i = 3; /* Hook into the general AT Keyboard driver. */ keyboard_at_set_mouse(ps2_write, dev); @@ -356,7 +356,7 @@ static const device_config_t ps2_config[] = { { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mouse_ps2_device = { diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index 2658a9e49..2edc342e9 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Serial Mouse devices. + * Implementation of Serial Mouse devices. * - * TODO: Add the Genius Serial Mouse. + * TODO: Add the Genius Serial Mouse. * * * - * Author: Fred N. van Kempen, + * Authors: Fred N. van Kempen, */ #include #include @@ -878,7 +878,7 @@ static const device_config_t ltsermouse_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mouse_mssystems_device = { diff --git a/src/device/phoenix_486_jumper.c b/src/device/phoenix_486_jumper.c index a0f6fdedf..bb1957690 100644 --- a/src/device/phoenix_486_jumper.c +++ b/src/device/phoenix_486_jumper.c @@ -1,14 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Phoenix 486 Jumper Readout + * Implementation of the Phoenix 486 Jumper Readout * - * Copyright 2020 Tiseno100 + * Authors: Tiseno100 + * + * Copyright 2020 Tiseno100 */ #include diff --git a/src/device/postcard.c b/src/device/postcard.c index e139d8592..f91736b1a 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of a port 80h POST diagnostic card. + * Implementation of a port 80h POST diagnostic card. * * * - * Author: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include diff --git a/src/device/serial.c b/src/device/serial.c index 3dd49590e..2434ca17c 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -12,13 +12,13 @@ * * * - * Author: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #include #include @@ -51,7 +51,8 @@ enum { static int next_inst = 0; static serial_device_t serial_devices[SERIAL_MAX]; -//#define ENABLE_SERIAL_CONSOLE 1 +// #define ENABLE_SERIAL_CONSOLE 1 + #ifdef ENABLE_SERIAL_LOG int serial_do_log = ENABLE_SERIAL_LOG; diff --git a/src/device/smbus_ali7101.c b/src/device/smbus_ali7101.c index 1ac3f1710..2777740dd 100644 --- a/src/device/smbus_ali7101.c +++ b/src/device/smbus_ali7101.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of a generic ALi M7101-compatible SMBus host - * controller. + * Implementation of a generic ALi M7101-compatible SMBus host + * controller. * - * Authors: RichardG, - * Miran Grca, + * Authors: RichardG, + * Miran Grca, * - * Copyright 2020,2021 RichardG. - * Copyright 2021 Miran Grca. + * Copyright 2020-2021 RichardG. + * Copyright 2021 Miran Grca. */ #include #include diff --git a/src/discord.c b/src/discord.c index d1966a93d..55f6d1544 100644 --- a/src/discord.c +++ b/src/discord.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Discord integration module. + * Discord integration module. * * * - * Authors: David Hrdlička, + * Authors: David Hrdlička, * - * Copyright 2019 David Hrdlička. + * Copyright 2019 David Hrdlička. */ #include #include @@ -132,7 +132,7 @@ discord_update_activity(int paused) } int -discord_load() +discord_load(void) { if (discord_handle != NULL) return (1); @@ -152,7 +152,7 @@ discord_load() } void -discord_init() +discord_init(void) { enum EDiscordResult result; struct DiscordCreateParams params; @@ -177,7 +177,7 @@ discord_init() } void -discord_close() +discord_close(void) { if (discord_core != NULL) discord_core->destroy(discord_core); @@ -187,7 +187,7 @@ discord_close() } void -discord_run_callbacks() +discord_run_callbacks(void) { if (discord_core == NULL) return; diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 34c373752..6d3abfc83 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 47584d113..2a20d8987 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Common code to handle all sorts of disk controllers. + * Common code to handle all sorts of disk controllers. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index c37d4782a..9df7725f1 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Driver for the ESDI controller (WD1007-vse1) for PC/AT. + * Driver for the ESDI controller (WD1007-vse1) for PC/AT. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #define _GNU_SOURCE #include diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index e5e96e364..80290c745 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -1,64 +1,64 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Driver for IBM PS/2 ESDI disk controller (MCA) + * Driver for IBM PS/2 ESDI disk controller (MCA) * - * AdapterID: 0xDDFF - * AdapterName: "ESDI Fixed Disk Controller" - * NumBytes 2 - * I/O base: 0x3510-0x3517 - * IRQ: 14 + * AdapterID: 0xDDFF + * AdapterName: "ESDI Fixed Disk Controller" + * NumBytes 2 + * I/O base: 0x3510-0x3517 + * IRQ: 14 * - * Primary Board pos[0]=XXxx xx0X 0x3510 - * Secondary Board pos[0]=XXxx xx1X 0x3518 + * Primary Board pos[0]=XXxx xx0X 0x3510 + * Secondary Board pos[0]=XXxx xx1X 0x3518 * - * DMA 5 pos[0]=XX01 01XX - * DMA 6 pos[0]=XX01 10XX - * DMA 7 pos[0]=XX01 11XX - * DMA 0 pos[0]=XX00 00XX - * DMA 1 pos[0]=XX00 01XX - * DMA 3 pos[0]=XX00 11XX - * DMA 4 pos[0]=XX01 00XX + * DMA 5 pos[0]=XX01 01XX + * DMA 6 pos[0]=XX01 10XX + * DMA 7 pos[0]=XX01 11XX + * DMA 0 pos[0]=XX00 00XX + * DMA 1 pos[0]=XX00 01XX + * DMA 3 pos[0]=XX00 11XX + * DMA 4 pos[0]=XX01 00XX * - * MCA Fairness ON pos[0]=X1XX XXXX - * MCA Fairness OFF pos[0]=X0XX XXXX + * MCA Fairness ON pos[0]=X1XX XXXX + * MCA Fairness OFF pos[0]=X0XX XXXX * - * ROM C000 pos[1]=XXXX 0000 - * ROM C400 pos[1]=XXXX 0001 - * ROM C800 pos[1]=XXXX 0010 - * ROM CC00 pos[1]=XXXX 0011 - * ROM D000 pos[1]=XXXX 0100 - * ROM D400 pos[1]=XXXX 0101 - * ROM D800 pos[1]=XXXX 0110 - * ROM DC00 pos[1]=XXXX 0111 - * ROM Disabled pos[1]=XXXX 1XXX + * ROM C000 pos[1]=XXXX 0000 + * ROM C400 pos[1]=XXXX 0001 + * ROM C800 pos[1]=XXXX 0010 + * ROM CC00 pos[1]=XXXX 0011 + * ROM D000 pos[1]=XXXX 0100 + * ROM D400 pos[1]=XXXX 0101 + * ROM D800 pos[1]=XXXX 0110 + * ROM DC00 pos[1]=XXXX 0111 + * ROM Disabled pos[1]=XXXX 1XXX * - * DMA Burst 8 pos[1]=XX01 XXXX - * DMA Burst 16 pos[1]=XX10 XXXX - * DMA Burst 24 pos[1]=XX11 XXXX - * DMA Disabled pos[1]=XX00 XXXX + * DMA Burst 8 pos[1]=XX01 XXXX + * DMA Burst 16 pos[1]=XX10 XXXX + * DMA Burst 24 pos[1]=XX11 XXXX + * DMA Disabled pos[1]=XX00 XXXX * - * Although this is an MCA device, meaning that the system - * software will take care of device configuration, the ESDI - * controller is a somewhat weird one.. it's I/O base address - * and IRQ channel are locked to 0x3510 and IRQ14, possibly - * to enforce compatibility with the IBM MFM disk controller - * that was also in use on these systems. All other settings, - * however, are auto-configured by the system software as - * shown above. + * Although this is an MCA device, meaning that the system + * software will take care of device configuration, the ESDI + * controller is a somewhat weird one.. it's I/O base address + * and IRQ channel are locked to 0x3510 and IRQ14, possibly + * to enforce compatibility with the IBM MFM disk controller + * that was also in use on these systems. All other settings, + * however, are auto-configured by the system software as + * shown above. * * * - * Authors: Sarah Walker, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Fred N. van Kempen, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2017,2018 Fred N. van Kempen. */ #include diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index a488d8aa2..2f544cfb9 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the IDE emulation for hard disks and ATAPI - * CD-ROM devices. + * Implementation of the IDE emulation for hard disks and ATAPI + * CD-ROM devices. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -1150,6 +1150,9 @@ ide_atapi_packet_write(ide_t *ide, uint32_t val, int length) bufferw = (uint16_t *) bufferb; bufferl = (uint32_t *) bufferb; + if (dev->packet_status == PHASE_DATA_IN) + return; + switch (length) { case 1: bufferb[dev->pos] = val & 0xff; @@ -1632,14 +1635,14 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); wait_time = seek_time > xfer_time ? seek_time : xfer_time; } else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize > 0)) { - sec_count = ide->secount ? ide->secount : 256; + sec_count = ide->secount ? ide->secount : 256; if (sec_count > ide->blocksize) sec_count = ide->blocksize; double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); wait_time = seek_time + xfer_time; } else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize == 0)) - wait_time = 200.0; + wait_time = 200.0; else { sec_count = 1; double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); @@ -1692,7 +1695,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_set_callback(ide, wait_time); } else if ((ide->type == IDE_HDD) && ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) { uint32_t sec_count = ide->secount ? ide->secount : 256; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); ide_set_callback(ide, seek_time + ide_get_xfer_time(ide, 2)); } else if ((val == WIN_IDENTIFY) || (val == WIN_SET_FEATURES)) ide_callback(ide); @@ -1865,8 +1868,8 @@ ide_read_data(ide_t *ide, int length) uint32_t sec_count = ide->secount ? ide->secount : 256; if (sec_count > ide->blocksize) sec_count = ide->blocksize; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); - double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); ide_set_callback(ide, seek_time + xfer_time); } else { ide_callback(ide); @@ -2090,18 +2093,27 @@ ide_board_callback(void *priv) #endif dev->ide[0]->atastat = DRDY_STAT | DSC_STAT; - if (dev->ide[0]->type == IDE_ATAPI) - dev->ide[0]->sc->status = DRDY_STAT | DSC_STAT; + if (dev->ide[0]->type == IDE_ATAPI) { + if (dev->ide[0]->sc->pad0) + dev->ide[0]->sc->status = DRDY_STAT | DSC_STAT; + else + dev->ide[0]->sc->status = 0; + } dev->ide[1]->atastat = DRDY_STAT | DSC_STAT; - if (dev->ide[1]->type == IDE_ATAPI) - dev->ide[1]->sc->status = DRDY_STAT | DSC_STAT; + if (dev->ide[1]->type == IDE_ATAPI) { + if (dev->ide[1]->sc->pad0) + dev->ide[1]->sc->status = DRDY_STAT | DSC_STAT; + else + dev->ide[1]->sc->status = 0; + } dev->cur_dev &= ~1; if (dev->diag) { dev->diag = 0; - ide_irq_raise(dev->ide[0]); + if ((dev->ide[0]->type != IDE_ATAPI) || dev->ide[0]->sc->pad0) + ide_irq_raise(dev->ide[0]); } } @@ -2157,7 +2169,7 @@ ide_callback(void *priv) ide_set_signature(ide); if (ide->type == IDE_ATAPI) { - ide->sc->error = 1; + ide->sc->error = 1; if (ide->device_reset) ide->device_reset(ide->sc); if (ide->sc->pad0) /* pad0 = early */ diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index c892bedd6..1dd92e79e 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the CMD PCI-0640B controller. + * Implementation of the CMD PCI-0640B controller. * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020 Miran Grca. */ #include #include diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index 98deaa459..df992b41b 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the CMD PCI-0646 controller. + * Implementation of the CMD PCI-0646 controller. * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020 Miran Grca. */ #include #include diff --git a/src/disk/hdc_ide_opti611.c b/src/disk/hdc_ide_opti611.c index d01f422bc..06eecb68f 100644 --- a/src/disk/hdc_ide_opti611.c +++ b/src/disk/hdc_ide_opti611.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C611/611A VLB IDE controller. + * Implementation of the OPTi 82C611/611A VLB IDE controller. - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020 Miran Grca. */ #include #include diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 5ce71325e..3809359b2 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of the SFF-8038i IDE Bus Master. + * Emulation of the SFF-8038i IDE Bus Master. * - * PRD format : - * word 0 - base address - * word 1 - bits 1-15 = byte count, bit 31 = end of transfer + * PRD format : + * word 0 - base address + * word 1 - bits 1-15 = byte count, bit 31 = end of transfer * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 1d6b618b5..d4edc4847 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -1,24 +1,24 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Driver for the IBM PC-AT MFM/RLL Fixed Disk controller. + * Driver for the IBM PC-AT MFM/RLL Fixed Disk controller. * - * This controller was a 16bit ISA card, and it used a WD1003 - * based design. Most cards were WD1003-WA2 or -WAH, where the - * -WA2 cards had a floppy controller as well (to save space.) + * This controller was a 16bit ISA card, and it used a WD1003 + * based design. Most cards were WD1003-WA2 or -WAH, where the + * -WA2 cards had a floppy controller as well (to save space.) * * * - * Authors: Sarah Walker, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 2f51699cf..f130a58d5 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -1,53 +1,53 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Driver for the IBM PC-XT Fixed Disk controller. + * Driver for the IBM PC-XT Fixed Disk controller. * - * The original controller shipped by IBM was made by Xebec, and - * several variations had been made: + * The original controller shipped by IBM was made by Xebec, and + * several variations had been made: * - * #1 Original, single drive (ST412), 10MB, 2 heads. - * #2 Update, single drive (ST412) but with option for a - * switch block that can be used to 'set' the actual - * drive type. Four switches are defined, where switches - * 1 and 2 define drive0, and switches 3 and 4 drive1. + * #1 Original, single drive (ST412), 10MB, 2 heads. + * #2 Update, single drive (ST412) but with option for a + * switch block that can be used to 'set' the actual + * drive type. Four switches are defined, where switches + * 1 and 2 define drive0, and switches 3 and 4 drive1. * - * 0 ON ON 306 2 0 - * 1 ON OFF 375 8 0 - * 2 OFF ON 306 6 256 - * 3 OFF OFF 306 4 0 + * 0 ON ON 306 2 0 + * 1 ON OFF 375 8 0 + * 2 OFF ON 306 6 256 + * 3 OFF OFF 306 4 0 * - * The latter option is the default, in use on boards - * without the switch block option. + * The latter option is the default, in use on boards + * without the switch block option. * - * #3 Another updated board, mostly to accomodate the new - * 20MB disk now being shipped. The controller can have - * up to 2 drives, the type of which is set using the - * switch block: + * #3 Another updated board, mostly to accomodate the new + * 20MB disk now being shipped. The controller can have + * up to 2 drives, the type of which is set using the + * switch block: * - * SW1 SW2 CYLS HD SPT WPC - * 0 ON ON 306 4 17 0 - * 1 ON OFF 612 4 17 0 (type 16) - * 2 OFF ON 615 4 17 300 (Seagate ST-225, 2) - * 3 OFF OFF 306 8 17 128 (IBM WD25, 13) + * SW1 SW2 CYLS HD SPT WPC + * 0 ON ON 306 4 17 0 + * 1 ON OFF 612 4 17 0 (type 16) + * 2 OFF ON 615 4 17 300 (Seagate ST-225, 2) + * 3 OFF OFF 306 8 17 128 (IBM WD25, 13) * - * Examples of #3 are IBM/Xebec, WD10004A-WX1 and ST11R. + * Examples of #3 are IBM/Xebec, WD10004A-WX1 and ST11R. * - * Since all controllers (including the ones made by DTC) use - * (mostly) the same API, we keep them all in this module. + * Since all controllers (including the ones made by DTC) use + * (mostly) the same API, we keep them all in this module. * * * - * Authors: Fred N. van Kempen, - * Sarah Walker, + * Authors: Fred N. van Kempen, + * Sarah Walker, * - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2008-2019 Sarah Walker. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -100,12 +100,12 @@ #define ST506_XT_TYPE_VICTOR_V86P 27 #define ST506_XT_TYPE_TOSHIBA_T1200 28 -#define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin" -#define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin" -#define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin" -#define ST11_BIOS_FILE_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin" -#define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" -#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" +#define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin" +#define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin" +#define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin" +#define ST11_BIOS_FILE_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin" +#define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" +#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" /* SuperBIOS was for both the WX1 and 27X, users jumpers readout to determine if to use 26 sectors per track, 26 -> 17 sectors per track translation, or 17 sectors per track. */ @@ -292,10 +292,33 @@ typedef struct { } hd_type_t; hd_type_t hd_types[4] = { - {306, 4, MFM_SECTORS}, /* type 0 */ - { 612, 4, MFM_SECTORS}, /* type 16 */ - { 615, 4, MFM_SECTORS}, /* type 2 */ - { 306, 8, MFM_SECTORS} /* type 13 */ + // clang-format off + { 306, 4, MFM_SECTORS}, /* type 0 */ + { 612, 4, MFM_SECTORS}, /* type 16 */ + { 615, 4, MFM_SECTORS}, /* type 2 */ + { 306, 8, MFM_SECTORS} /* type 13 */ + // clang-format on +}; + +hd_type_t hd_types_olivetti[16] = { + // clang-format off + { 697, 5, MFM_SECTORS}, + { 612, 4, MFM_SECTORS}, /* type 16 */ + { 612, 4, MFM_SECTORS}, /* type 16 */ + { 306, 4, MFM_SECTORS}, /* type 0 */ + { 612, 8, MFM_SECTORS}, + { 820, 6, MFM_SECTORS}, + { 820, 6, MFM_SECTORS}, + { 823, 10, MFM_SECTORS}, + { 981, 5, MFM_SECTORS}, + { 981, 5, MFM_SECTORS}, + {1024, 8, MFM_SECTORS}, + {1024, 9, MFM_SECTORS}, + { 872, 5, MFM_SECTORS}, + { 612, 4, MFM_SECTORS}, /* type 16 */ + { 612, 4, MFM_SECTORS}, /* type 16 */ + { 306, 4, MFM_SECTORS} /* "not present" with the second hard disk */ + // clang-format on }; #ifdef ENABLE_ST506_XT_LOG @@ -1272,9 +1295,9 @@ mem_write(uint32_t addr, uint8_t val, void *priv) addr -= dev->bios_addr; switch (dev->type) { - case ST506_XT_TYPE_ST11M: /* ST-11M */ - case ST506_XT_TYPE_ST11R: /* ST-11R */ - mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ + case ST506_XT_TYPE_ST11M: /* ST-11M */ + case ST506_XT_TYPE_ST11R: /* ST-11R */ + mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ break; default: @@ -1322,9 +1345,9 @@ mem_read(uint32_t addr, void *priv) } break; - case ST506_XT_TYPE_ST11M: /* ST-11M */ - case ST506_XT_TYPE_ST11R: /* ST-11R */ - mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ + case ST506_XT_TYPE_ST11M: /* ST-11M */ + case ST506_XT_TYPE_ST11R: /* ST-11R */ + mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ break; /* default: @@ -1430,29 +1453,40 @@ loadhd(hdc_t *dev, int c, int d, const char *fn) /* Set the "drive type" switches for the IBM Xebec controller. */ static void -set_switches(hdc_t *dev) +set_switches(hdc_t *dev, hd_type_t *hdt, int num) { drive_t *drive; int c, d; + int e; dev->switches = 0x00; for (d = 0; d < MFM_NUM; d++) { drive = &dev->drives[d]; - if (!drive->present) + if (!drive->present) { + if (dev->type == ST506_XT_TYPE_WD1002A_WX1_NOBIOS) + dev->switches |= (0x33 << (d ? 0 : 2)); continue; + } - for (c = 0; c < 4; c++) { - if ((drive->spt == hd_types[c].spt) && (drive->hpc == hd_types[c].hpc) && (drive->tracks == hd_types[c].tracks)) { - dev->switches |= (c << (d ? 0 : 2)); + for (c = 0; c < num; c++) { + /* Does the Xebec also support more than 4 types? */ + if ((drive->spt == hdt[c].spt) && (drive->hpc == hdt[c].hpc) && (drive->tracks == hdt[c].tracks)) { + /* Olivetti M24/M240: Move the upper 2 bites up by 2 bits, as the + layout is as follows: D0_3 D0_2 D1_3 D1_2 D0_1 D0_0 D1_1 D1_0. */ + if (dev->type == ST506_XT_TYPE_WD1002A_WX1_NOBIOS) + e = (c & 0x03) | ((c >> 2) << 4); + else + e = c; + dev->switches |= (e << (d ? 0 : 2)); break; } } #ifdef ENABLE_ST506_XT_LOG st506_xt_log("ST506: "); - if (c == 4) + if (c == num) st506_xt_log("*WARNING* drive%i unsupported", d); else st506_xt_log("drive%i is type %i", d, c); @@ -1538,16 +1572,9 @@ st506_init(const device_t *info) break; case ST506_XT_TYPE_WD1002A_WX1_NOBIOS: /* Western Digital WD1002A-WX1 (MFM, No BIOS) */ + /* Supported base addresses: 320h, 324h, 328h, 32Ch. */ dev->nr_err = ERR_NOT_AVAILABLE; fn = NULL; - /* The switches are read in reverse: 0 = closed, 1 = open. - Both open means MFM, 17 sectors per track. */ - dev->switches = 0x30; /* autobios */ - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - if (dev->irq == 2) - dev->switches |= 0x40; - dev->bios_addr = device_get_config_hex20("bios_addr"); break; case ST506_XT_TYPE_WD1004A_WX1: /* Western Digital WD1004A-WX1 (MFM) */ @@ -1613,7 +1640,7 @@ st506_init(const device_t *info) break; case ST506_XT_TYPE_TOSHIBA_T1200: /* Toshiba T1200 */ - fn = NULL; + fn = NULL; dev->base = 0x01f0; dev->switches = 0x0c; break; @@ -1650,7 +1677,9 @@ st506_init(const device_t *info) /* For the Xebec, set the switches now. */ if (dev->type == ST506_XT_TYPE_XEBEC) - set_switches(dev); + set_switches(dev, (hd_type_t *) hd_types, 4); + else if (dev->type == ST506_XT_TYPE_WD1002A_WX1_NOBIOS) + set_switches(dev, (hd_type_t *) hd_types_olivetti, 16); /* Initial "active" drive parameters. */ for (c = 0; c < MFM_NUM; c++) { diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index f623d82f5..339547699 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -1,35 +1,35 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * XT-IDE controller emulation. + * XT-IDE controller emulation. * - * The XT-IDE project is intended to allow 8-bit ("XT") systems - * to use regular IDE drives. IDE is a standard based on the - * 16b PC/AT design, and so a special board (with its own BIOS) - * had to be created for this. + * The XT-IDE project is intended to allow 8-bit ("XT") systems + * to use regular IDE drives. IDE is a standard based on the + * 16b PC/AT design, and so a special board (with its own BIOS) + * had to be created for this. * - * XT-IDE is *NOT* the same as XTA, or X-IDE, which is an older - * standard where the actual MFM/RLL controller for the PC/XT - * was placed on the hard drive (hard drives where its drive - * type would end in "X" or "XT", such as the 8425XT.) This was - * more or less the original IDE, but since those systems were - * already on their way out, the newer IDE standard based on the - * PC/AT controller and 16b design became the IDE we now know. + * XT-IDE is *NOT* the same as XTA, or X-IDE, which is an older + * standard where the actual MFM/RLL controller for the PC/XT + * was placed on the hard drive (hard drives where its drive + * type would end in "X" or "XT", such as the 8425XT.) This was + * more or less the original IDE, but since those systems were + * already on their way out, the newer IDE standard based on the + * PC/AT controller and 16b design became the IDE we now know. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017-2018 Fred N. van Kempen. */ #include #include diff --git a/src/disk/hdd.c b/src/disk/hdd.c index ee731b046..61a355b44 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Common code to handle all sorts of hard disk images. + * Common code to handle all sorts of hard disk images. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include @@ -53,7 +53,7 @@ hdd_string_to_bus(char *str, int cdrom) if (!strcmp(str, "mfm") || !strcmp(str, "rll")) { if (cdrom) { no_cdrom: - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4099); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2131, (wchar_t *) IDS_4099); return (0); } @@ -419,25 +419,20 @@ hdd_zones_init(hard_disk_t *hdd) } static hdd_preset_t hdd_speed_presets[] = { - {.name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32}, - - { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, - - { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, - - { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, - - { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, - - { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, - - { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - - { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + // clang-format off + { .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, + { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, + { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, + { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + // clang-format on }; int -hdd_preset_get_num() +hdd_preset_get_num(void) { return sizeof(hdd_speed_presets) / sizeof(hdd_preset_t); } diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 7100acdd6..1b59ac570 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handling of hard disk image files. + * Handling of hard disk image files. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #define _GNU_SOURCE #include @@ -348,7 +348,6 @@ hdd_image_load(int id) } else { /* Failed for another reason */ hdd_image_log("Failed for another reason\n"); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); return 0; } } else { diff --git a/src/disk/hdd_table.c b/src/disk/hdd_table.c index ae03e91a8..d75dc7e8d 100644 --- a/src/disk/hdd_table.c +++ b/src/disk/hdd_table.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the IDE emulation for hard disks and ATAPI - * CD-ROM devices. + * Implementation of the IDE emulation for hard disks and ATAPI + * CD-ROM devices. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include @@ -27,7 +27,7 @@ unsigned int hdd_table[128][3] = { // clang-format off - { 306, 4, 17 }, /* 0 - 7 */ + { 306, 4, 17 }, /* 0 - 7 */ { 615, 2, 17 }, { 306, 4, 26 }, { 1024, 2, 17 }, @@ -36,7 +36,7 @@ unsigned int hdd_table[128][3] = { { 614, 4, 17 }, { 615, 4, 17 }, - { 670, 4, 17 }, /* 8 - 15 */ + { 670, 4, 17 }, /* 8 - 15 */ { 697, 4, 17 }, { 987, 3, 17 }, { 820, 4, 17 }, @@ -45,7 +45,7 @@ unsigned int hdd_table[128][3] = { { 733, 5, 17 }, { 615, 6, 17 }, - { 462, 8, 17 }, /* 016-023 */ + { 462, 8, 17 }, /* 016-023 */ { 306, 8, 26 }, { 615, 4, 26 }, { 1024, 4, 17 }, @@ -54,7 +54,7 @@ unsigned int hdd_table[128][3] = { { 932, 5, 17 }, { 1024, 2, 40 }, - { 809, 6, 17 }, /* 024-031 */ + { 809, 6, 17 }, /* 024-031 */ { 976, 5, 17 }, { 977, 5, 17 }, { 698, 7, 17 }, @@ -63,7 +63,7 @@ unsigned int hdd_table[128][3] = { { 615, 8, 17 }, { 989, 5, 17 }, - { 820, 4, 26 }, /* 032-039 */ + { 820, 4, 26 }, /* 032-039 */ { 1024, 5, 17 }, { 733, 7, 17 }, { 754, 7, 17 }, @@ -72,7 +72,7 @@ unsigned int hdd_table[128][3] = { { 615, 6, 26 }, { 462, 8, 26 }, - { 830, 7, 17 }, /* 040-047 */ + { 830, 7, 17 }, /* 040-047 */ { 855, 7, 17 }, { 751, 8, 17 }, { 1024, 4, 26 }, @@ -81,7 +81,7 @@ unsigned int hdd_table[128][3] = { { 855, 5, 26 }, { 977, 7, 17 }, - { 987, 7, 17 }, /* 048-055 */ + { 987, 7, 17 }, /* 048-055 */ { 1024, 7, 17 }, { 823, 4, 38 }, { 925, 8, 17 }, @@ -90,7 +90,7 @@ unsigned int hdd_table[128][3] = { { 977, 5, 26 }, { 698, 7, 26 }, - { 699, 7, 26 }, /* 056-063 */ + { 699, 7, 26 }, /* 056-063 */ { 940, 8, 17 }, { 615, 8, 26 }, { 1024, 5, 26 }, @@ -99,7 +99,7 @@ unsigned int hdd_table[128][3] = { { 823, 10, 17 }, { 754, 11, 17 }, - { 830, 10, 17 }, /* 064-071 */ + { 830, 10, 17 }, /* 064-071 */ { 925, 9, 17 }, { 1224, 7, 17 }, { 940, 6, 26 }, @@ -108,7 +108,7 @@ unsigned int hdd_table[128][3] = { { 1024, 9, 17 }, { 965, 10, 17 }, - { 969, 5, 34 }, /* 072-079 */ + { 969, 5, 34 }, /* 072-079 */ { 980, 10, 17 }, { 960, 5, 35 }, { 918, 11, 17 }, @@ -117,7 +117,7 @@ unsigned int hdd_table[128][3] = { { 1024, 7, 26 }, { 1024, 11, 17 }, - { 940, 8, 26 }, /* 080-087 */ + { 940, 8, 26 }, /* 080-087 */ { 776, 8, 33 }, { 755, 16, 17 }, { 1024, 12, 17 }, @@ -126,7 +126,7 @@ unsigned int hdd_table[128][3] = { { 830, 10, 26 }, { 925, 9, 26 }, - { 960, 9, 26 }, /* 088-095 */ + { 960, 9, 26 }, /* 088-095 */ { 1024, 13, 17 }, { 1224, 11, 17 }, { 900, 15, 17 }, @@ -135,7 +135,7 @@ unsigned int hdd_table[128][3] = { { 918, 15, 17 }, { 1524, 4, 39 }, - { 1024, 9, 26 }, /* 096-103 */ + { 1024, 9, 26 }, /* 096-103 */ { 1024, 14, 17 }, { 965, 10, 26 }, { 980, 10, 26 }, @@ -144,7 +144,7 @@ unsigned int hdd_table[128][3] = { { 1024, 15, 17 }, { 1024, 16, 17 }, - { 1224, 15, 17 }, /* 104-111 */ + { 1224, 15, 17 }, /* 104-111 */ { 755, 16, 26 }, { 903, 8, 46 }, { 984, 10, 34 }, @@ -153,7 +153,7 @@ unsigned int hdd_table[128][3] = { { 1023, 15, 26 }, { 684, 16, 38 }, - { 1930, 4, 62 }, /* 112-119 */ + { 1930, 4, 62 }, /* 112-119 */ { 967, 16, 31 }, { 1013, 10, 63 }, { 1218, 15, 36 }, @@ -162,7 +162,7 @@ unsigned int hdd_table[128][3] = { { 702, 16, 63 }, { 1002, 13, 63 }, - { 854, 16, 63 }, /* 119-127 */ + { 854, 16, 63 }, /* 119-127 */ { 987, 16, 63 }, { 995, 16, 63 }, { 1024, 16, 63 }, @@ -170,5 +170,5 @@ unsigned int hdd_table[128][3] = { { 1120, 16, 59 }, { 1054, 16, 63 }, { 0, 0, 0 } -// clang-format on + // clang-format on }; diff --git a/src/disk/minivhd/CMakeLists.txt b/src/disk/minivhd/CMakeLists.txt index 0cba1fb39..ec6caff81 100644 --- a/src/disk/minivhd/CMakeLists.txt +++ b/src/disk/minivhd/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(minivhd STATIC cwalk.c libxml2_encoding.c minivhd_convert.c diff --git a/src/disk/mo.c b/src/disk/mo.c index f73ec049f..2180fe544 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of a generic Magneto-Optical Disk drive - * commands, for both ATAPI and SCSI usage. + * Implementation of a generic Magneto-Optical Disk drive + * commands, for both ATAPI and SCSI usage. * * * - * Authors: Natalia Portillo - * Miran Grca, - * Fred N. van Kempen, + * Authors: Natalia Portillo + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2020,2021 Natalia Portillo. - * Copyright 2020,2021 Miran Grca. - * Copyright 2020,2021 Fred N. van Kempen + * Copyright 2020-2021 Natalia Portillo. + * Copyright 2020-2021 Miran Grca. + * Copyright 2020-2021 Fred N. van Kempen */ #include #include diff --git a/src/disk/zip.c b/src/disk/zip.c index 885aa92a5..959a5fbbe 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Iomega ZIP drive with SCSI(-like) - * commands, for both ATAPI and SCSI usage. + * Implementation of the Iomega ZIP drive with SCSI(-like) + * commands, for both ATAPI and SCSI usage. * * * - * Author: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2018,2019 Miran Grca. + * Copyright 2018-2019 Miran Grca. */ #include #include diff --git a/src/floppy/CMakeLists.txt b/src/floppy/CMakeLists.txt index a30bebd71..005e5bc57 100644 --- a/src/floppy/CMakeLists.txt +++ b/src/floppy/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(fdd OBJECT fdd.c fdc.c fdc_magitronic.c fdc_pii15xb.c fdi2raw.c fdd_common.c diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 360fee1e6..fbc95be8a 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the NEC uPD-765 and compatible floppy disk - * controller. + * Implementation of the NEC uPD-765 and compatible floppy disk + * controller. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -2373,17 +2373,17 @@ const device_t fdc_xt_device = { }; const device_t fdc_xt_sec_device = { - .name = "PC/XT Floppy Drive Controller (Secondary)", + .name = "PC/XT Floppy Drive Controller (Secondary)", .internal_name = "fdc_xt", - .flags = FDC_FLAG_SEC, - .local = 0, - .init = fdc_init, - .close = fdc_close, - .reset = fdc_reset, + .flags = FDC_FLAG_SEC, + .local = 0, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t fdc_xt_t1x00_device = { @@ -2457,17 +2457,17 @@ const device_t fdc_at_device = { }; const device_t fdc_at_sec_device = { - .name = "PC/AT Floppy Drive Controller (Secondary)", + .name = "PC/AT Floppy Drive Controller (Secondary)", .internal_name = "fdc_at_sec", - .flags = 0, - .local = FDC_FLAG_AT | FDC_FLAG_SEC, - .init = fdc_init, - .close = fdc_close, - .reset = fdc_reset, + .flags = 0, + .local = FDC_FLAG_AT | FDC_FLAG_SEC, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t fdc_at_actlow_device = { diff --git a/src/floppy/fdc_magitronic.c b/src/floppy/fdc_magitronic.c index 8b3c2b325..d71721d7b 100644 --- a/src/floppy/fdc_magitronic.c +++ b/src/floppy/fdc_magitronic.c @@ -1,17 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Magitronic B215 XT-FDC Controller. + * Implementation of the Magitronic B215 XT-FDC Controller. * - * Authors: Tiseno100 - * - * Copyright 2021 Tiseno100 + * Authors: Tiseno100 * + * Copyright 2021 Tiseno100 */ #include @@ -125,7 +124,7 @@ static const device_config_t b215_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t fdc_b215_device = { diff --git a/src/floppy/fdc_pii15xb.c b/src/floppy/fdc_pii15xb.c index d8b687502..be471face 100644 --- a/src/floppy/fdc_pii15xb.c +++ b/src/floppy/fdc_pii15xb.c @@ -140,7 +140,7 @@ static const device_config_t pii_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t fdc_pii151b_device = { diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 1ea1ca9ff..a6ccb6da5 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the floppy drive emulation. + * Implementation of the floppy drive emulation. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018,2019 Fred N. van Kempen. */ #include #include @@ -75,7 +75,7 @@ typedef struct { fdd_t fdd[FDD_NUM]; -char floppyfns[FDD_NUM][512]; +char floppyfns[FDD_NUM][512]; char *fdd_image_history[FDD_NUM][FLOPPY_IMAGE_HISTORY]; pc_timer_t fdd_poll_time[FDD_NUM]; @@ -383,13 +383,11 @@ fdd_is_dd(int drive) return (drive_types[fdd[drive].type].flags & 0x70) == 0x10; } -#if 0 int fdd_is_hd(int drive) { return drive_types[fdd[drive].type].flags & FLAG_HOLE1; } -#endif int fdd_is_ed(int drive) diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 1a7609737..7509dd3a5 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the 86F floppy image format (stores the - * data in the form of FM/MFM-encoded transitions) which also - * forms the core of the emulator's floppy disk emulation. + * Implementation of the 86F floppy image format (stores the + * data in the form of FM/MFM-encoded transitions) which also + * forms the core of the emulator's floppy disk emulation. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 Fred N. van Kempen. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018-2019 Fred N. van Kempen. */ #include #include diff --git a/src/floppy/fdd_common.c b/src/floppy/fdd_common.c index 97f9393ea..28dea0735 100644 --- a/src/floppy/fdd_common.c +++ b/src/floppy/fdd_common.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Shared code for all the floppy modules. + * Shared code for all the floppy modules. * * * - * Author: Fred N. van Kempen, + * Authors: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2018 Fred N. van Kempen. */ #include #include diff --git a/src/floppy/fdd_fdi.c b/src/floppy/fdd_fdi.c index ae5a0140d..5d09d8df2 100644 --- a/src/floppy/fdd_fdi.c +++ b/src/floppy/fdd_fdi.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the FDI floppy stream image format - * interface to the FDI2RAW module. + * Implementation of the FDI floppy stream image format + * interface to the FDI2RAW module. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2018 Fred N. van Kempen. */ #include #include diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index d193efb7f..830a96b0e 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the IMD floppy image format. + * Implementation of the IMD floppy image format. * * * - * Authors: Fred N. van Kempen, - * Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 Fred N. van Kempen. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018-2019 Fred N. van Kempen. */ #include #include diff --git a/src/floppy/fdd_img.c b/src/floppy/fdd_img.c index 497f41997..3ebfeefd9 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -1,27 +1,27 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the raw sector-based floppy image format, - * as well as the Japanese FDI, CopyQM, and FDF formats. + * Implementation of the raw sector-based floppy image format, + * as well as the Japanese FDI, CopyQM, and FDF formats. * - * NOTE: This file is still a disaster, needs to be cleaned up and - * re-merged with the other files. Much of it is generic to - * all formats. + * NOTE: This file is still a disaster, needs to be cleaned up and + * re-merged with the other files. Much of it is generic to + * all formats. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018-2019 Fred N. van Kempen. */ #include #include @@ -40,30 +40,29 @@ #include <86box/fdd_img.h> #include <86box/fdc.h> - typedef struct { - FILE *f; - uint8_t track_data[2][50000]; - int sectors, tracks, sides; - uint8_t sector_size; - int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */ - int dmf; - int track; - int track_width; - uint32_t base; - uint8_t gap2_size; - uint8_t gap3_size; - uint16_t disk_flags; - uint16_t track_flags; - uint8_t sector_pos_side[256][256]; - uint16_t sector_pos[256][256]; - uint8_t current_sector_pos_side; - uint16_t current_sector_pos; - uint8_t *disk_data; - uint8_t is_cqm; - uint8_t disk_at_once; - uint8_t interleave; - uint8_t skew; + FILE *f; + uint8_t track_data[2][50000]; + int sectors, tracks, sides; + uint8_t sector_size; + int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */ + int dmf; + int track; + int track_width; + uint32_t base; + uint8_t gap2_size; + uint8_t gap3_size; + uint16_t disk_flags; + uint16_t track_flags; + uint8_t sector_pos_side[256][256]; + uint16_t sector_pos[256][256]; + uint8_t current_sector_pos_side; + uint16_t current_sector_pos; + uint8_t *disk_data; + uint8_t is_cqm; + uint8_t disk_at_once; + uint8_t interleave; + uint8_t skew; } img_t; @@ -289,162 +288,153 @@ int img_do_log = ENABLE_IMG_LOG; static void img_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (img_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } + if (img_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } } #else -#define img_log(fmt, ...) +# define img_log(fmt, ...) #endif - /* Generic */ static int sector_size_code(int sector_size) { - switch(sector_size) { - case 128: - return(0); + switch (sector_size) { + case 128: + return (0); - case 256: - return(1); + case 256: + return (1); - default: - case 512: - return(2); + default: + case 512: + return (2); - case 1024: - return(3); + case 1024: + return (3); - case 2048: - return(4); + case 2048: + return (4); - case 4096: - return(5); + case 4096: + return (5); - case 8192: - return(6); + case 8192: + return (6); - case 16384: - return(7); + case 16384: + return (7); } } - static int bps_is_valid(uint16_t bps) { int i; for (i = 0; i <= 8; i++) { - if (bps == (128 << i)) return(1); + if (bps == (128 << i)) + return (1); } - return(0); + return (0); } - static int first_byte_is_valid(uint8_t first_byte) { - switch(first_byte) { - case 0x60: - case 0xE9: - case 0xEB: - return(1); + switch (first_byte) { + case 0x60: + case 0xE9: + case 0xEB: + return (1); - default: - break; + default: + break; } - return(0); + return (0); } - -#define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] +#define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] #define xdf_disk_sector xdf_disk_layout[current_xdft][!is_t0][array_sector] - static int interleave(int sector, int skew, int track_spt) { uint32_t skewed_i; uint32_t adjusted_r; - uint32_t add = (track_spt & 1); + uint32_t add = (track_spt & 1); uint32_t adjust = (track_spt >> 1); - skewed_i = (sector + skew) % track_spt; + skewed_i = (sector + skew) % track_spt; adjusted_r = (skewed_i >> 1) + 1; if (skewed_i & 1) - adjusted_r += (adjust + add); + adjusted_r += (adjust + add); - return(adjusted_r); + return (adjusted_r); } - static void write_back(int drive) { - img_t *dev = img[drive]; - int ssize = 128 << ((int) dev->sector_size); - int side, size; + img_t *dev = img[drive]; + int ssize = 128 << ((int) dev->sector_size); + int side, size; - if (dev->f == NULL) return; + if (dev->f == NULL) + return; - if (dev->disk_at_once) return; + if (dev->disk_at_once) + return; if (fseek(dev->f, dev->base + (dev->track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) - pclog("IMG write_back(): Error seeking to the beginning of the file\n"); + pclog("IMG write_back(): Error seeking to the beginning of the file\n"); for (side = 0; side < dev->sides; side++) { - size = dev->sectors * ssize; - if (fwrite(dev->track_data[side], 1, size, dev->f) != size) - fatal("IMG write_back(): Error writing data\n"); + size = dev->sectors * ssize; + if (fwrite(dev->track_data[side], 1, size, dev->f) != size) + fatal("IMG write_back(): Error writing data\n"); } } - static uint16_t disk_flags(int drive) { img_t *dev = img[drive]; - return(dev->disk_flags); + return (dev->disk_flags); } - static uint16_t side_flags(int drive) { img_t *dev = img[drive]; - return(dev->track_flags); + return (dev->track_flags); } - static void set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) { img_t *dev = img[drive]; dev->current_sector_pos_side = dev->sector_pos_side[h][r]; - dev->current_sector_pos = dev->sector_pos[h][r]; + dev->current_sector_pos = dev->sector_pos[h][r]; } - static uint8_t poll_read_data(int drive, int side, uint16_t pos) { img_t *dev = img[drive]; - return(dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos]); + return (dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos]); } - static void poll_write_data(int drive, int side, uint16_t pos, uint8_t data) { @@ -453,56 +443,55 @@ poll_write_data(int drive, int side, uint16_t pos, uint8_t data) dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos] = data; } - static int format_conditions(int drive) { - img_t *dev = img[drive]; - int temp = (fdc_get_format_sectors(img_fdc) == dev->sectors); + img_t *dev = img[drive]; + int temp = (fdc_get_format_sectors(img_fdc) == dev->sectors); temp = temp && (fdc_get_format_n(img_fdc) == dev->sector_size); temp = temp && (dev->xdf_type == 0); - return(temp); + return (temp); } - static void img_seek(int drive, int track) { - img_t *dev = img[drive]; - int side; - int current_xdft = dev->xdf_type - 1; - int read_bytes = 0; - uint8_t id[4] = { 0, 0, 0, 0 }; - int is_t0, sector, current_pos, img_pos, sr, sside, total, array_sector, buf_side, buf_pos; - int ssize = 128 << ((int) dev->sector_size); + img_t *dev = img[drive]; + int side; + int current_xdft = dev->xdf_type - 1; + int read_bytes = 0; + uint8_t id[4] = { 0, 0, 0, 0 }; + int is_t0, sector, current_pos, img_pos, sr, sside, total, array_sector, buf_side, buf_pos; + int ssize = 128 << ((int) dev->sector_size); uint32_t cur_pos = 0; - if (dev->f == NULL) return; + if (dev->f == NULL) + return; if (!dev->track_width && fdd_doublestep_40(drive)) - track /= 2; + track /= 2; dev->track = track; d86f_set_cur_track(drive, track); is_t0 = (track == 0) ? 1 : 0; - if (! dev->disk_at_once) { - if (fseek(dev->f, dev->base + (track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) - fatal("img_seek(): Error seeking\n"); + if (!dev->disk_at_once) { + if (fseek(dev->f, dev->base + (track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) + fatal("img_seek(): Error seeking\n"); } for (side = 0; side < dev->sides; side++) { - if (dev->disk_at_once) { - cur_pos = (track * dev->sectors * ssize * dev->sides) + (side * dev->sectors * ssize); - memcpy(dev->track_data[side], dev->disk_data + cur_pos, dev->sectors * ssize); - } else { - read_bytes = fread(dev->track_data[side], 1, dev->sectors * ssize, dev->f); - if (read_bytes < (dev->sectors * ssize)) - memset(dev->track_data[side] + read_bytes, 0xf6, (dev->sectors * ssize) - read_bytes); - } + if (dev->disk_at_once) { + cur_pos = (track * dev->sectors * ssize * dev->sides) + (side * dev->sectors * ssize); + memcpy(dev->track_data[side], dev->disk_data + cur_pos, dev->sectors * ssize); + } else { + read_bytes = fread(dev->track_data[side], 1, dev->sectors * ssize, dev->f); + if (read_bytes < (dev->sectors * ssize)) + memset(dev->track_data[side] + read_bytes, 0xf6, (dev->sectors * ssize) - read_bytes); + } } d86f_reset_index_hole_pos(drive, 0); @@ -512,136 +501,134 @@ img_seek(int drive, int track) d86f_destroy_linked_lists(drive, 1); if (track > dev->tracks) { - d86f_zero_track(drive); - return; + d86f_zero_track(drive); + return; } if (!dev->xdf_type || dev->is_cqm) { - for (side = 0; side < dev->sides; side++) { - current_pos = d86f_prepare_pretrack(drive, side, 0); + for (side = 0; side < dev->sides; side++) { + current_pos = d86f_prepare_pretrack(drive, side, 0); - for (sector = 0; sector < dev->sectors; sector++) { - if (dev->is_cqm) { - if (dev->interleave) - sr = interleave(sector, dev->skew, dev->sectors); - else { - sr = sector + 1; - sr += dev->skew; - if (sr > dev->sectors) - sr -= dev->sectors; - } - } else { - if (dev->gap3_size < 68) - sr = interleave(sector, 1, dev->sectors); - else - sr = dev->dmf ? (dmf_r[sector]) : (sector + 1); - } - id[0] = track; - id[1] = side; - id[2] = sr; - id[3] = dev->sector_size; - dev->sector_pos_side[side][sr] = side; - dev->sector_pos[side][sr] = (sr - 1) * ssize; - current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[side][(sr - 1) * ssize], ssize, dev->gap2_size, dev->gap3_size, 0); + for (sector = 0; sector < dev->sectors; sector++) { + if (dev->is_cqm) { + if (dev->interleave) + sr = interleave(sector, dev->skew, dev->sectors); + else { + sr = sector + 1; + sr += dev->skew; + if (sr > dev->sectors) + sr -= dev->sectors; + } + } else { + if (dev->gap3_size < 68) + sr = interleave(sector, 1, dev->sectors); + else + sr = dev->dmf ? (dmf_r[sector]) : (sector + 1); + } + id[0] = track; + id[1] = side; + id[2] = sr; + id[3] = dev->sector_size; + dev->sector_pos_side[side][sr] = side; + dev->sector_pos[side][sr] = (sr - 1) * ssize; + current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[side][(sr - 1) * ssize], ssize, dev->gap2_size, dev->gap3_size, 0); - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } + if (sector == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } + } } else { - total = dev->sectors; - img_pos = 0; - sside = 0; + total = dev->sectors; + img_pos = 0; + sside = 0; - /* Pass 1, get sector positions in the image. */ - for (sector = 0; sector < xdf_logical_sectors[current_xdft][!is_t0]; sector++) { - if (is_t0) { - img_pos = (sector % total) << 9; - sside = (sector >= total) ? 1 : 0; - } + /* Pass 1, get sector positions in the image. */ + for (sector = 0; sector < xdf_logical_sectors[current_xdft][!is_t0]; sector++) { + if (is_t0) { + img_pos = (sector % total) << 9; + sside = (sector >= total) ? 1 : 0; + } - if (xdf_img_sector.word) { - dev->sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside; - dev->sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos; - } + if (xdf_img_sector.word) { + dev->sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside; + dev->sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos; + } - if (! is_t0) { - img_pos += (128 << (xdf_img_sector.id.r & 7)); - if (img_pos >= (total << 9)) sside = 1; - img_pos %= (total << 9); - } - } + if (!is_t0) { + img_pos += (128 << (xdf_img_sector.id.r & 7)); + if (img_pos >= (total << 9)) + sside = 1; + img_pos %= (total << 9); + } + } - /* Pass 2, prepare the actual track. */ - for (side = 0; side < dev->sides; side++) { - current_pos = d86f_prepare_pretrack(drive, side, 0); + /* Pass 2, prepare the actual track. */ + for (side = 0; side < dev->sides; side++) { + current_pos = d86f_prepare_pretrack(drive, side, 0); - for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++) { - array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector; - buf_side = dev->sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; - buf_pos = dev->sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; + for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++) { + array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector; + buf_side = dev->sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; + buf_pos = dev->sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; - id[0] = track; - id[1] = xdf_disk_sector.id.h; - id[2] = xdf_disk_sector.id.r; + id[0] = track; + id[1] = xdf_disk_sector.id.h; + id[2] = xdf_disk_sector.id.r; - if (is_t0) { - id[3] = 2; - current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0); - } else { - id[3] = id[2] & 7; - ssize = (128 << id[3]); - current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0); - } + if (is_t0) { + id[3] = 2; + current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0); + } else { + id[3] = id[2] & 7; + ssize = (128 << id[3]); + current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0); + } - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } + if (sector == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } + } } } - void img_init(void) { memset(img, 0x00, sizeof(img)); } - int is_divisible(uint16_t total, uint8_t what) { if ((total != 0) && (what != 0)) - return ((total % what) == 0); + return ((total % what) == 0); else - return 0; + return 0; } - void img_load(int drive, char *fn) { uint16_t bpb_bps; uint16_t bpb_total; - uint8_t bpb_mid; /* Media type ID. */ - uint8_t bpb_sectors; - uint8_t bpb_sides; - uint8_t cqm, ddi, fdf, fdi; + uint8_t bpb_mid; /* Media type ID. */ + uint8_t bpb_sectors; + uint8_t bpb_sides; + uint8_t cqm, ddi, fdf, fdi; uint16_t comment_len = 0; - int16_t block_len = 0; - uint32_t cur_pos = 0; - uint8_t rep_byte = 0; - uint8_t run = 0; - uint8_t real_run = 0; + int16_t block_len = 0; + uint32_t cur_pos = 0; + uint8_t rep_byte = 0; + uint8_t run = 0; + uint8_t real_run = 0; uint8_t *bpos; uint16_t track_bytes = 0; uint8_t *literal; - img_t *dev; - int temp_rate; - int guess = 0; - int size; - int i; + img_t *dev; + int temp_rate; + int guess = 0; + int size; + int i; ext = path_get_extension(fn); @@ -650,568 +637,572 @@ img_load(int drive, char *fn) writeprot[drive] = 0; /* Allocate a drive block. */ - dev = (img_t *)malloc(sizeof(img_t)); + dev = (img_t *) malloc(sizeof(img_t)); memset(dev, 0x00, sizeof(img_t)); dev->f = plat_fopen(fn, "rb+"); if (dev->f == NULL) { - dev->f = plat_fopen(fn, "rb"); - if (dev->f == NULL) { - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - writeprot[drive] = 1; + dev->f = plat_fopen(fn, "rb"); + if (dev->f == NULL) { + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } + writeprot[drive] = 1; } if (ui_writeprot[drive]) - writeprot[drive] = 1; + writeprot[drive] = 1; fwriteprot[drive] = writeprot[drive]; cqm = ddi = fdf = fdi = 0; dev->interleave = dev->skew = 0; - if (! strcasecmp(ext, "DDI")) { - ddi = 1; - dev->base = 0x2400; + if (!strcasecmp(ext, "DDI")) { + ddi = 1; + dev->base = 0x2400; } else - dev->base = 0; + dev->base = 0; - if (! strcasecmp(ext, "FDI")) { - /* This is a Japanese FDI image, so let's read the header */ - img_log("img_load(): File is a Japanese FDI image...\n"); - fseek(dev->f, 0x10, SEEK_SET); - (void) !fread(&bpb_bps, 1, 2, dev->f); - fseek(dev->f, 0x0C, SEEK_SET); - (void) !fread(&size, 1, 4, dev->f); - bpb_total = size / bpb_bps; - fseek(dev->f, 0x08, SEEK_SET); - (void) !fread(&(dev->base), 1, 4, dev->f); - fseek(dev->f, dev->base + 0x15, SEEK_SET); - bpb_mid = fgetc(dev->f); - if (bpb_mid < 0xF0) - bpb_mid = 0xF0; - fseek(dev->f, 0x14, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, 0x18, SEEK_SET); - bpb_sides = fgetc(dev->f); - fseek(dev->f, dev->base, SEEK_SET); - first_byte = fgetc(dev->f); + if (!strcasecmp(ext, "FDI")) { + /* This is a Japanese FDI image, so let's read the header */ + img_log("img_load(): File is a Japanese FDI image...\n"); + fseek(dev->f, 0x10, SEEK_SET); + (void) !fread(&bpb_bps, 1, 2, dev->f); + fseek(dev->f, 0x0C, SEEK_SET); + (void) !fread(&size, 1, 4, dev->f); + bpb_total = size / bpb_bps; + fseek(dev->f, 0x08, SEEK_SET); + (void) !fread(&(dev->base), 1, 4, dev->f); + fseek(dev->f, dev->base + 0x15, SEEK_SET); + bpb_mid = fgetc(dev->f); + if (bpb_mid < 0xF0) + bpb_mid = 0xF0; + fseek(dev->f, 0x14, SEEK_SET); + bpb_sectors = fgetc(dev->f); + fseek(dev->f, 0x18, SEEK_SET); + bpb_sides = fgetc(dev->f); + fseek(dev->f, dev->base, SEEK_SET); + first_byte = fgetc(dev->f); - fdi = 1; - cqm = 0; - dev->disk_at_once = 0; - fdf = 0; + fdi = 1; + cqm = 0; + dev->disk_at_once = 0; + fdf = 0; } else { - /* Read the first four bytes. */ - fseek(dev->f, 0x00, SEEK_SET); - first_byte = fgetc(dev->f); - fseek(dev->f, 0x01, SEEK_SET); - second_byte = fgetc(dev->f); - fseek(dev->f, 0x02, SEEK_SET); - third_byte = fgetc(dev->f); - fseek(dev->f, 0x03, SEEK_SET); - fourth_byte = fgetc(dev->f); + /* Read the first four bytes. */ + fseek(dev->f, 0x00, SEEK_SET); + first_byte = fgetc(dev->f); + fseek(dev->f, 0x01, SEEK_SET); + second_byte = fgetc(dev->f); + fseek(dev->f, 0x02, SEEK_SET); + third_byte = fgetc(dev->f); + fseek(dev->f, 0x03, SEEK_SET); + fourth_byte = fgetc(dev->f); - if ((first_byte == 0x1A) && (second_byte == 'F') && - (third_byte == 'D') && (fourth_byte == 'F')) { - /* This is a FDF image. */ - img_log("img_load(): File is a FDF image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - fclose(dev->f); - dev->f = plat_fopen(fn, "rb"); + if ((first_byte == 0x1A) && (second_byte == 'F') && (third_byte == 'D') && (fourth_byte == 'F')) { + /* This is a FDF image. */ + img_log("img_load(): File is a FDF image...\n"); + fwriteprot[drive] = writeprot[drive] = 1; + fclose(dev->f); + dev->f = plat_fopen(fn, "rb"); - fdf = 1; - cqm = 0; - dev->disk_at_once = 1; + fdf = 1; + cqm = 0; + dev->disk_at_once = 1; - fseek(dev->f, 0x50, SEEK_SET); - (void) !fread(&dev->tracks, 1, 4, dev->f); + fseek(dev->f, 0x50, SEEK_SET); + (void) !fread(&dev->tracks, 1, 4, dev->f); - /* Decode the entire file - pass 1, no write to buffer, determine length. */ - fseek(dev->f, 0x80, SEEK_SET); - size = 0; - track_bytes = 0; - bpos = dev->disk_data; - while (! feof(dev->f)) { - if (! track_bytes) { - /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(dev->f); - (void) !fread(&track_bytes, 1, 2, dev->f); - img_log("Block header: %02X %04X ", first_byte, track_bytes); - /* Read the length of encoded data block. */ - (void) !fread(&track_bytes, 1, 2, dev->f); - img_log("%04X\n", track_bytes); - } + /* Decode the entire file - pass 1, no write to buffer, determine length. */ + fseek(dev->f, 0x80, SEEK_SET); + size = 0; + track_bytes = 0; + bpos = dev->disk_data; + while (!feof(dev->f)) { + if (!track_bytes) { + /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ + first_byte = fgetc(dev->f); + (void) !fread(&track_bytes, 1, 2, dev->f); + img_log("Block header: %02X %04X ", first_byte, track_bytes); + /* Read the length of encoded data block. */ + (void) !fread(&track_bytes, 1, 2, dev->f); + img_log("%04X\n", track_bytes); + } - if (feof(dev->f)) break; + if (feof(dev->f)) + break; - if (first_byte == 0xFF) break; + if (first_byte == 0xFF) + break; - if (first_byte) { - run = fgetc(dev->f); + if (first_byte) { + run = fgetc(dev->f); - /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ - track_bytes--; + /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ + track_bytes--; - if (run & 0x80) { - /* Repeat. */ - track_bytes--; - rep_byte = fgetc(dev->f); - } else { - /* Literal. */ - track_bytes -= (run & 0x7f); - literal = (uint8_t *)malloc(run & 0x7f); - (void) !fread(literal, 1, (run & 0x7f), dev->f); - free(literal); - } - size += (run & 0x7f); - if (!track_bytes) - size -= fdf_suppress_final_byte; - } else { - /* Literal block. */ - size += (track_bytes - fdf_suppress_final_byte); - literal = (uint8_t *)malloc(track_bytes); - (void) !fread(literal, 1, track_bytes, dev->f); - free(literal); - track_bytes = 0; - } + if (run & 0x80) { + /* Repeat. */ + track_bytes--; + rep_byte = fgetc(dev->f); + } else { + /* Literal. */ + track_bytes -= (run & 0x7f); + literal = (uint8_t *) malloc(run & 0x7f); + (void) !fread(literal, 1, (run & 0x7f), dev->f); + free(literal); + } + size += (run & 0x7f); + if (!track_bytes) + size -= fdf_suppress_final_byte; + } else { + /* Literal block. */ + size += (track_bytes - fdf_suppress_final_byte); + literal = (uint8_t *) malloc(track_bytes); + (void) !fread(literal, 1, track_bytes, dev->f); + free(literal); + track_bytes = 0; + } - if (feof(dev->f)) break; - } + if (feof(dev->f)) + break; + } - /* Allocate the buffer. */ - dev->disk_data = (uint8_t *)malloc(size); + /* Allocate the buffer. */ + dev->disk_data = (uint8_t *) malloc(size); - /* Decode the entire file - pass 2, write to buffer. */ - fseek(dev->f, 0x80, SEEK_SET); - track_bytes = 0; - bpos = dev->disk_data; - while(! feof(dev->f)) { - if (! track_bytes) { - /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(dev->f); - (void) !fread(&track_bytes, 1, 2, dev->f); - img_log("Block header: %02X %04X ", first_byte, track_bytes); - /* Read the length of encoded data block. */ - (void) !fread(&track_bytes, 1, 2, dev->f); - img_log("%04X\n", track_bytes); - } + /* Decode the entire file - pass 2, write to buffer. */ + fseek(dev->f, 0x80, SEEK_SET); + track_bytes = 0; + bpos = dev->disk_data; + while (!feof(dev->f)) { + if (!track_bytes) { + /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ + first_byte = fgetc(dev->f); + (void) !fread(&track_bytes, 1, 2, dev->f); + img_log("Block header: %02X %04X ", first_byte, track_bytes); + /* Read the length of encoded data block. */ + (void) !fread(&track_bytes, 1, 2, dev->f); + img_log("%04X\n", track_bytes); + } - if (feof(dev->f)) break; + if (feof(dev->f)) + break; - if (first_byte == 0xFF) break; + if (first_byte == 0xFF) + break; - if (first_byte) { - run = fgetc(dev->f); - real_run = (run & 0x7f); + if (first_byte) { + run = fgetc(dev->f); + real_run = (run & 0x7f); - /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ - track_bytes--; + /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ + track_bytes--; - if (run & 0x80) { - /* Repeat. */ - track_bytes--; - if (! track_bytes) - real_run -= fdf_suppress_final_byte; - rep_byte = fgetc(dev->f); - if (real_run) - memset(bpos, rep_byte, real_run); - } else { - /* Literal. */ - track_bytes -= real_run; - literal = (uint8_t *) malloc(real_run); - (void) !fread(literal, 1, real_run, dev->f); - if (! track_bytes) - real_run -= fdf_suppress_final_byte; - if (run & 0x7f) - memcpy(bpos, literal, real_run); - free(literal); - } - bpos += real_run; - } else { - /* Literal block. */ - literal = (uint8_t *) malloc(track_bytes); - (void) !fread(literal, 1, track_bytes, dev->f); - memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte); - free(literal); - bpos += (track_bytes - fdf_suppress_final_byte); - track_bytes = 0; - } + if (run & 0x80) { + /* Repeat. */ + track_bytes--; + if (!track_bytes) + real_run -= fdf_suppress_final_byte; + rep_byte = fgetc(dev->f); + if (real_run) + memset(bpos, rep_byte, real_run); + } else { + /* Literal. */ + track_bytes -= real_run; + literal = (uint8_t *) malloc(real_run); + (void) !fread(literal, 1, real_run, dev->f); + if (!track_bytes) + real_run -= fdf_suppress_final_byte; + if (run & 0x7f) + memcpy(bpos, literal, real_run); + free(literal); + } + bpos += real_run; + } else { + /* Literal block. */ + literal = (uint8_t *) malloc(track_bytes); + (void) !fread(literal, 1, track_bytes, dev->f); + memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte); + free(literal); + bpos += (track_bytes - fdf_suppress_final_byte); + track_bytes = 0; + } - if (feof(dev->f)) break; - } + if (feof(dev->f)) + break; + } - first_byte = *dev->disk_data; + first_byte = *dev->disk_data; - bpb_bps = *(uint16_t *)(dev->disk_data + 0x0B); - bpb_total = *(uint16_t *)(dev->disk_data + 0x13); - bpb_mid = *(dev->disk_data + 0x15); - bpb_sectors = *(dev->disk_data + 0x18); - bpb_sides = *(dev->disk_data + 0x1A); + bpb_bps = *(uint16_t *) (dev->disk_data + 0x0B); + bpb_total = *(uint16_t *) (dev->disk_data + 0x13); + bpb_mid = *(dev->disk_data + 0x15); + bpb_sectors = *(dev->disk_data + 0x18); + bpb_sides = *(dev->disk_data + 0x1A); - /* Jump ahead to determine the image's geometry. */ - goto jump_if_fdf; - } + /* Jump ahead to determine the image's geometry. */ + goto jump_if_fdf; + } - if (((first_byte == 'C') && (second_byte == 'Q')) || - ((first_byte == 'c') && (second_byte == 'q'))) { - img_log("img_load(): File is a CopyQM image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - fclose(dev->f); - dev->f = plat_fopen(fn, "rb"); + if (((first_byte == 'C') && (second_byte == 'Q')) || ((first_byte == 'c') && (second_byte == 'q'))) { + img_log("img_load(): File is a CopyQM image...\n"); + fwriteprot[drive] = writeprot[drive] = 1; + fclose(dev->f); + dev->f = plat_fopen(fn, "rb"); - fseek(dev->f, 0x03, SEEK_SET); - (void) !fread(&bpb_bps, 1, 2, dev->f); + fseek(dev->f, 0x03, SEEK_SET); + (void) !fread(&bpb_bps, 1, 2, dev->f); #if 0 fseek(dev->f, 0x0B, SEEK_SET); (void) !fread(&bpb_total, 1, 2, dev->f); #endif - fseek(dev->f, 0x10, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, 0x12, SEEK_SET); - bpb_sides = fgetc(dev->f); - fseek(dev->f, 0x5B, SEEK_SET); - dev->tracks = fgetc(dev->f); + fseek(dev->f, 0x10, SEEK_SET); + bpb_sectors = fgetc(dev->f); + fseek(dev->f, 0x12, SEEK_SET); + bpb_sides = fgetc(dev->f); + fseek(dev->f, 0x5B, SEEK_SET); + dev->tracks = fgetc(dev->f); - bpb_total = ((uint16_t)bpb_sectors) * ((uint16_t) bpb_sides) * dev->tracks; + bpb_total = ((uint16_t) bpb_sectors) * ((uint16_t) bpb_sides) * dev->tracks; - fseek(dev->f, 0x74, SEEK_SET); - dev->interleave = fgetc(dev->f); - fseek(dev->f, 0x76, SEEK_SET); - dev->skew = fgetc(dev->f); + fseek(dev->f, 0x74, SEEK_SET); + dev->interleave = fgetc(dev->f); + fseek(dev->f, 0x76, SEEK_SET); + dev->skew = fgetc(dev->f); - dev->disk_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - memset(dev->disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); + dev->disk_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); + memset(dev->disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - fseek(dev->f, 0x6F, SEEK_SET); - (void) !fread(&comment_len, 1, 2, dev->f); + fseek(dev->f, 0x6F, SEEK_SET); + (void) !fread(&comment_len, 1, 2, dev->f); - fseek(dev->f, -1, SEEK_END); - size = ftell(dev->f) + 1; + fseek(dev->f, -1, SEEK_END); + size = ftell(dev->f) + 1; - fseek(dev->f, 133 + comment_len, SEEK_SET); + fseek(dev->f, 133 + comment_len, SEEK_SET); - cur_pos = 0; + cur_pos = 0; - while(! feof(dev->f)) { - (void) !fread(&block_len, 1, 2, dev->f); + while (!feof(dev->f)) { + (void) !fread(&block_len, 1, 2, dev->f); - if (! feof(dev->f)) { - if (block_len < 0) { - rep_byte = fgetc(dev->f); - block_len = -block_len; - if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { - block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - memset(dev->disk_data + cur_pos, rep_byte, block_len); - break; - } else { - memset(dev->disk_data + cur_pos, rep_byte, block_len); - cur_pos += block_len; - } - } else if (block_len > 0) { - if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { - block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); - break; - } else { - (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); - cur_pos += block_len; - } - } - } - } - img_log("Finished reading CopyQM image data\n"); + if (!feof(dev->f)) { + if (block_len < 0) { + rep_byte = fgetc(dev->f); + block_len = -block_len; + if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { + block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; + memset(dev->disk_data + cur_pos, rep_byte, block_len); + break; + } else { + memset(dev->disk_data + cur_pos, rep_byte, block_len); + cur_pos += block_len; + } + } else if (block_len > 0) { + if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { + block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; + (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); + break; + } else { + (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); + cur_pos += block_len; + } + } + } + } + img_log("Finished reading CopyQM image data\n"); - cqm = 1; - dev->disk_at_once = 1; - fdf = 0; - first_byte = *dev->disk_data; - } else { - dev->disk_at_once = 0; - /* Read the BPB */ - if (ddi) { - img_log("img_load(): File is a DDI image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - } else - img_log("img_load(): File is a raw image...\n"); - fseek(dev->f, dev->base + 0x0B, SEEK_SET); - (void) !fread(&bpb_bps, 1, 2, dev->f); - fseek(dev->f, dev->base + 0x13, SEEK_SET); - (void) !fread(&bpb_total, 1, 2, dev->f); - fseek(dev->f, dev->base + 0x15, SEEK_SET); - bpb_mid = fgetc(dev->f); - fseek(dev->f, dev->base + 0x18, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, dev->base + 0x1A, SEEK_SET); - bpb_sides = fgetc(dev->f); + cqm = 1; + dev->disk_at_once = 1; + fdf = 0; + first_byte = *dev->disk_data; + } else { + dev->disk_at_once = 0; + /* Read the BPB */ + if (ddi) { + img_log("img_load(): File is a DDI image...\n"); + fwriteprot[drive] = writeprot[drive] = 1; + } else + img_log("img_load(): File is a raw image...\n"); + fseek(dev->f, dev->base + 0x0B, SEEK_SET); + (void) !fread(&bpb_bps, 1, 2, dev->f); + fseek(dev->f, dev->base + 0x13, SEEK_SET); + (void) !fread(&bpb_total, 1, 2, dev->f); + fseek(dev->f, dev->base + 0x15, SEEK_SET); + bpb_mid = fgetc(dev->f); + fseek(dev->f, dev->base + 0x18, SEEK_SET); + bpb_sectors = fgetc(dev->f); + fseek(dev->f, dev->base + 0x1A, SEEK_SET); + bpb_sides = fgetc(dev->f); - cqm = 0; - } + cqm = 0; + } - fseek(dev->f, -1, SEEK_END); - size = ftell(dev->f) + 1; - if (ddi) - size -= 0x2400; + fseek(dev->f, -1, SEEK_END); + size = ftell(dev->f) + 1; + if (ddi) + size -= 0x2400; jump_if_fdf: - if (!ddi) - dev->base = 0; - fdi = 0; + if (!ddi) + dev->base = 0; + fdi = 0; } - dev->sides = 2; + dev->sides = 2; dev->sector_size = 2; img_log("BPB reports %i sides and %i bytes per sector (%i sectors total)\n", - bpb_sides, bpb_bps, bpb_total); + bpb_sides, bpb_bps, bpb_total); - /* Invalid conditions: */ - guess = (bpb_sides < 1); /* Sides < 1; */ - guess = guess || (bpb_sides > 2); /* Sides > 2; */ - guess = guess || !bps_is_valid(bpb_bps); /* Invalid number of bytes per sector; */ - guess = guess || !first_byte_is_valid(first_byte); /* Invalid first bytes; */ - guess = guess || !is_divisible(bpb_total, bpb_sectors); /* Total sectors not divisible by sectors per track; */ - guess = guess || !is_divisible(bpb_total, bpb_sides); /* Total sectors not divisible by sides. */ + /* Invalid conditions: */ + guess = (bpb_sides < 1); /* Sides < 1; */ + guess = guess || (bpb_sides > 2); /* Sides > 2; */ + guess = guess || !bps_is_valid(bpb_bps); /* Invalid number of bytes per sector; */ + guess = guess || !first_byte_is_valid(first_byte); /* Invalid first bytes; */ + guess = guess || !is_divisible(bpb_total, bpb_sectors); /* Total sectors not divisible by sectors per track; */ + guess = guess || !is_divisible(bpb_total, bpb_sides); /* Total sectors not divisible by sides. */ guess = guess || !fdd_get_check_bpb(drive); guess = guess && !fdi; guess = guess && !cqm; if (guess) { - /* - * The BPB is giving us a wacky number of sides and/or bytes - * per sector, therefore it is most probably not a BPB at all, - * so we have to guess the parameters from file size. - */ - if (size <= (160*1024)) { - dev->sectors = 8; - dev->tracks = 40; - dev->sides = 1; - } else if (size <= (180*1024)) { - dev->sectors = 9; - dev->tracks = 40; - dev->sides = 1; - } else if (size <= (315*1024)) { - dev->sectors = 9; - dev->tracks = 70; - dev->sides = 1; - } else if (size <= (320*1024)) { - dev->sectors = 8; - dev->tracks = 40; - } else if (size <= (320*1024)) { - dev->sectors = 8; - dev->tracks = 40; - } else if (size <= (360*1024)) { /*DD 360K*/ - dev->sectors = 9; - dev->tracks = 40; - } else if (size <= (400*1024)) { /*DEC RX50*/ - dev->sectors = 10; - dev->tracks = 80; - dev->sides = 1; - } else if (size <= (640*1024)) { /*DD 640K*/ - dev->sectors = 8; - dev->tracks = 80; - } else if (size <= (720*1024)) { /*DD 720K*/ - dev->sectors = 9; - dev->tracks = 80; - } else if (size <= (800*1024)) { /*DD*/ - dev->sectors = 10; - dev->tracks = 80; - } else if (size <= (880*1024)) { /*DD*/ - dev->sectors = 11; - dev->tracks = 80; - } else if (size <= (960*1024)) { /*DD*/ - dev->sectors = 12; - dev->tracks = 80; - } else if (size <= (1040*1024)) { /*DD*/ - dev->sectors = 13; - dev->tracks = 80; - } else if (size <= (1120*1024)) { /*DD*/ - dev->sectors = 14; - dev->tracks = 80; - } else if (size <= 1228800) { /*HD 1.2MB*/ - dev->sectors = 15; - dev->tracks = 80; - } else if (size <= 1261568) { /*HD 1.25MB Japanese*/ - dev->sectors = 8; - dev->tracks = 77; - dev->sector_size = 3; - } else if (size <= 1474560) { /*HD 1.44MB*/ - dev->sectors = 18; - dev->tracks = 80; - } else if (size <= 1556480) { /*HD*/ - dev->sectors = 19; - dev->tracks = 80; - } else if (size <= 1638400) { /*HD 1024 sector*/ - dev->sectors = 10; - dev->tracks = 80; - dev->sector_size = 3; - } else if (size <= 1720320) { /*DMF (Windows 95) */ - dev->sectors = 21; - dev->tracks = 80; - } else if (size <= 1741824) { - dev->sectors = 21; - dev->tracks = 81; - } else if (size <= 1763328) { - dev->sectors = 21; - dev->tracks = 82; - } else if (size <= 1802240) { /*HD 1024 sector*/ - dev->sectors = 22; - dev->tracks = 80; - dev->sector_size = 3; - } else if (size == 1884160) { /*XDF (OS/2 Warp)*/ - dev->sectors = 23; - dev->tracks = 80; - } else if (size <= 2949120) { /*ED*/ - dev->sectors = 36; - dev->tracks = 80; - } else if (size <= 3194880) { /*ED*/ - dev->sectors = 39; - dev->tracks = 80; - } else if (size <= 3276800) { /*ED*/ - dev->sectors = 40; - dev->tracks = 80; - } else if (size <= 3358720) { /*ED, maximum possible size*/ - dev->sectors = 41; - dev->tracks = 80; - } else if (size <= 3440640) { /*ED, maximum possible size*/ - dev->sectors = 42; - dev->tracks = 80; + /* + * The BPB is giving us a wacky number of sides and/or bytes + * per sector, therefore it is most probably not a BPB at all, + * so we have to guess the parameters from file size. + */ + if (size <= (160 * 1024)) { + dev->sectors = 8; + dev->tracks = 40; + dev->sides = 1; + } else if (size <= (180 * 1024)) { + dev->sectors = 9; + dev->tracks = 40; + dev->sides = 1; + } else if (size <= (315 * 1024)) { + dev->sectors = 9; + dev->tracks = 70; + dev->sides = 1; + } else if (size <= (320 * 1024)) { + dev->sectors = 8; + dev->tracks = 40; + } else if (size <= (320 * 1024)) { + dev->sectors = 8; + dev->tracks = 40; + } else if (size <= (360 * 1024)) { /*DD 360K*/ + dev->sectors = 9; + dev->tracks = 40; + } else if (size <= (400 * 1024)) { /*DEC RX50*/ + dev->sectors = 10; + dev->tracks = 80; + dev->sides = 1; + } else if (size <= (640 * 1024)) { /*DD 640K*/ + dev->sectors = 8; + dev->tracks = 80; + } else if (size <= (720 * 1024)) { /*DD 720K*/ + dev->sectors = 9; + dev->tracks = 80; + } else if (size <= (800 * 1024)) { /*DD*/ + dev->sectors = 10; + dev->tracks = 80; + } else if (size <= (880 * 1024)) { /*DD*/ + dev->sectors = 11; + dev->tracks = 80; + } else if (size <= (960 * 1024)) { /*DD*/ + dev->sectors = 12; + dev->tracks = 80; + } else if (size <= (1040 * 1024)) { /*DD*/ + dev->sectors = 13; + dev->tracks = 80; + } else if (size <= (1120 * 1024)) { /*DD*/ + dev->sectors = 14; + dev->tracks = 80; + } else if (size <= 1228800) { /*HD 1.2MB*/ + dev->sectors = 15; + dev->tracks = 80; + } else if (size <= 1261568) { /*HD 1.25MB Japanese*/ + dev->sectors = 8; + dev->tracks = 77; + dev->sector_size = 3; + } else if (size <= 1474560) { /*HD 1.44MB*/ + dev->sectors = 18; + dev->tracks = 80; + } else if (size <= 1556480) { /*HD*/ + dev->sectors = 19; + dev->tracks = 80; + } else if (size <= 1638400) { /*HD 1024 sector*/ + dev->sectors = 10; + dev->tracks = 80; + dev->sector_size = 3; + } else if (size <= 1720320) { /*DMF (Windows 95) */ + dev->sectors = 21; + dev->tracks = 80; + } else if (size <= 1741824) { + dev->sectors = 21; + dev->tracks = 81; + } else if (size <= 1763328) { + dev->sectors = 21; + dev->tracks = 82; + } else if (size <= 1802240) { /*HD 1024 sector*/ + dev->sectors = 22; + dev->tracks = 80; + dev->sector_size = 3; + } else if (size == 1884160) { /*XDF (OS/2 Warp)*/ + dev->sectors = 23; + dev->tracks = 80; + } else if (size <= 2949120) { /*ED*/ + dev->sectors = 36; + dev->tracks = 80; + } else if (size <= 3194880) { /*ED*/ + dev->sectors = 39; + dev->tracks = 80; + } else if (size <= 3276800) { /*ED*/ + dev->sectors = 40; + dev->tracks = 80; + } else if (size <= 3358720) { /*ED, maximum possible size*/ + dev->sectors = 41; + dev->tracks = 80; + } else if (size <= 3440640) { /*ED, maximum possible size*/ + dev->sectors = 42; + dev->tracks = 80; #if 0 } else if (size <= 3440640) { /*HD 1024 sector*/ dev->sectors = 21; dev->tracks = 80; dev->sector_size = 3; #endif - } else if (size <= 3604480) { /*HD 1024 sector*/ - dev->sectors = 22; - dev->tracks = 80; - dev->sector_size = 3; - } else if (size <= 3610624) { /*ED, maximum possible size*/ - dev->sectors = 41; - dev->tracks = 86; - } else if (size <= 3698688) { /*ED, maximum possible size*/ - dev->sectors = 42; - dev->tracks = 86; - } else { - img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } + } else if (size <= 3604480) { /*HD 1024 sector*/ + dev->sectors = 22; + dev->tracks = 80; + dev->sector_size = 3; + } else if (size <= 3610624) { /*ED, maximum possible size*/ + dev->sectors = 41; + dev->tracks = 86; + } else if (size <= 3698688) { /*ED, maximum possible size*/ + dev->sectors = 42; + dev->tracks = 86; + } else { + img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } - bpb_sides = dev->sides; - bpb_sectors = dev->sectors; - bpb_total = size >> (dev->sector_size + 7); + bpb_sides = dev->sides; + bpb_sectors = dev->sectors; + bpb_total = size >> (dev->sector_size + 7); } else { - /* The BPB readings appear to be valid, so let's set the values. */ - if (fdi) { - /* The image is a Japanese FDI, therefore we read the number of tracks from the header. */ - if (fseek(dev->f, 0x1C, SEEK_SET) == -1) - fatal("Japanese FDI: Failed when seeking to 0x1C\n"); - (void) !fread(&(dev->tracks), 1, 4, dev->f); - } else { - if (!cqm && !fdf) { - /* Number of tracks = number of total sectors divided by sides times sectors per track. */ - dev->tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors)); - } - } + /* The BPB readings appear to be valid, so let's set the values. */ + if (fdi) { + /* The image is a Japanese FDI, therefore we read the number of tracks from the header. */ + if (fseek(dev->f, 0x1C, SEEK_SET) == -1) + fatal("Japanese FDI: Failed when seeking to 0x1C\n"); + (void) !fread(&(dev->tracks), 1, 4, dev->f); + } else { + if (!cqm && !fdf) { + /* Number of tracks = number of total sectors divided by sides times sectors per track. */ + dev->tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors)); + } + } - /* The rest we just set directly from the BPB. */ - dev->sectors = bpb_sectors; - dev->sides = bpb_sides; + /* The rest we just set directly from the BPB. */ + dev->sectors = bpb_sectors; + dev->sides = bpb_sides; - /* The sector size. */ - dev->sector_size = sector_size_code(bpb_bps); + /* The sector size. */ + dev->sector_size = sector_size_code(bpb_bps); - temp_rate = 0xFF; + temp_rate = 0xFF; } for (i = 0; i < 6; i++) { - if ((dev->sectors <= maximum_sectors[dev->sector_size][i]) || (dev->sectors == xdf_sectors[dev->sector_size][i])) { - bit_rate_300 = bit_rates_300[i]; - temp_rate = rates[i]; - dev->disk_flags = holes[i] << 1; - dev->xdf_type = (dev->sectors == xdf_sectors[dev->sector_size][i]) ? xdf_types[dev->sector_size][i] : 0; - if ((bit_rate_300 == 500.0) && (dev->sectors == 21) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { - /* This is a DMF floppy, set the flag so we know to interleave the sectors. */ - dev->dmf = 1; - } else { - if ((bit_rate_300 == 500.0) && (dev->sectors == 22) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { - /* This is marked specially because of the track flag (a RPM slow down is needed). */ - dev->interleave = 2; - } - dev->dmf = 0; - } + if ((dev->sectors <= maximum_sectors[dev->sector_size][i]) || (dev->sectors == xdf_sectors[dev->sector_size][i])) { + bit_rate_300 = bit_rates_300[i]; + temp_rate = rates[i]; + dev->disk_flags = holes[i] << 1; + dev->xdf_type = (dev->sectors == xdf_sectors[dev->sector_size][i]) ? xdf_types[dev->sector_size][i] : 0; + if ((bit_rate_300 == 500.0) && (dev->sectors == 21) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { + /* This is a DMF floppy, set the flag so we know to interleave the sectors. */ + dev->dmf = 1; + } else { + if ((bit_rate_300 == 500.0) && (dev->sectors == 22) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { + /* This is marked specially because of the track flag (a RPM slow down is needed). */ + dev->interleave = 2; + } + dev->dmf = 0; + } - img_log("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, dev->disk_flags >> 1, dev->dmf, dev->xdf_type); - break; - } + img_log("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, dev->disk_flags >> 1, dev->dmf, dev->xdf_type); + break; + } } if (temp_rate == 0xFF) { - img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; + img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; } dev->gap2_size = (temp_rate == 3) ? 41 : 22; if (dev->dmf) - dev->gap3_size = 8; + dev->gap3_size = 8; else { - if (dev->sectors == -1) - dev->gap3_size = 8; - else - dev->gap3_size = gap3_sizes[temp_rate][dev->sector_size][dev->sectors]; + if (dev->sectors == -1) + dev->gap3_size = 8; + else + dev->gap3_size = gap3_sizes[temp_rate][dev->sector_size][dev->sectors]; } - if (! dev->gap3_size) { - img_log("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; + if (!dev->gap3_size) { + img_log("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; } dev->track_width = 0; if (dev->tracks > 43) - dev->track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */ + dev->track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */ if (dev->sides == 2) - dev->disk_flags |= 8; /* If the has 2 sides, mark it as such. */ + dev->disk_flags |= 8; /* If the has 2 sides, mark it as such. */ if (dev->interleave == 2) { - dev->interleave = 1; - dev->disk_flags |= 0x60; + dev->interleave = 1; + dev->disk_flags |= 0x60; } - dev->track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */ - dev->track_flags |= temp_rate & 3; /* Data rate. */ + dev->track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */ + dev->track_flags |= temp_rate & 3; /* Data rate. */ if (temp_rate & 4) - dev->track_flags |= 0x20; /* RPM. */ + dev->track_flags |= 0x20; /* RPM. */ dev->is_cqm = cqm; img_log("Disk flags: %i, track flags: %i\n", - dev->disk_flags, dev->track_flags); + dev->disk_flags, dev->track_flags); /* Set up the drive unit. */ img[drive] = dev; /* Attach this format to the D86F engine. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = side_flags; - d86f_handler[drive].writeback = write_back; - d86f_handler[drive].set_sector = set_sector; - d86f_handler[drive].read_data = poll_read_data; - d86f_handler[drive].write_data = poll_write_data; + d86f_handler[drive].disk_flags = disk_flags; + d86f_handler[drive].side_flags = side_flags; + d86f_handler[drive].writeback = write_back; + d86f_handler[drive].set_sector = set_sector; + d86f_handler[drive].read_data = poll_read_data; + d86f_handler[drive].write_data = poll_write_data; d86f_handler[drive].format_conditions = format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; + d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + d86f_handler[drive].index_hole_pos = null_index_hole_pos; + d86f_handler[drive].get_raw_size = common_get_raw_size; + d86f_handler[drive].check_crc = 1; d86f_set_version(drive, 0x0063); drives[drive].seek = img_seek; @@ -1219,30 +1210,29 @@ jump_if_fdf: d86f_common_handlers(drive); } - void img_close(int drive) { img_t *dev = img[drive]; - if (dev == NULL) return; + if (dev == NULL) + return; d86f_unregister(drive); if (dev->f != NULL) { - fclose(dev->f); - dev->f = NULL; + fclose(dev->f); + dev->f = NULL; } if (dev->disk_data != NULL) - free(dev->disk_data); + free(dev->disk_data); /* Release the memory. */ free(dev); img[drive] = NULL; } - void img_set_fdc(void *fdc) { diff --git a/src/floppy/fdd_mfm.c b/src/floppy/fdd_mfm.c index e8a0336ef..5196bcbe0 100644 --- a/src/floppy/fdd_mfm.c +++ b/src/floppy/fdd_mfm.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the HxC MFM image format. + * Implementation of the HxC MFM image format. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2018,2019 Miran Grca. + * Copyright 2018-2019 Miran Grca. */ #include #include diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index e5e253781..4b478baba 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -1,32 +1,32 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Teledisk floppy image format. + * Implementation of the Teledisk floppy image format. * * * - * Authors: Milodrag Milanovic, - * Haruhiko OKUMURA, - * Haruyasu YOSHIZAKI, - * Kenji RIKITAKE, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Milodrag Milanovic, + * Haruhiko OKUMURA, + * Haruyasu YOSHIZAKI, + * Kenji RIKITAKE, + * Miran Grca, + * Fred N. van Kempen, * - * Based on Japanese version 29-NOV-1988 - * LZSS coded by Haruhiko OKUMURA - * Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI - * Edited and translated to English by Kenji RIKITAKE + * Based on Japanese version 29-NOV-1988 + * LZSS coded by Haruhiko OKUMURA + * Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI + * Edited and translated to English by Kenji RIKITAKE * - * Copyright 2013-2019 Milodrag Milanovic. - * Copyright 1988-2019 Haruhiko OKUMURA. - * Copyright 1988-2019 Haruyasu YOSHIZAKI. - * Copyright 1988-2019 Kenji RIKITAKE. - * Copyright 2016-2019 Miran Grca. + * Copyright 2013-2019 Milodrag Milanovic. + * Copyright 1988-2019 Haruhiko OKUMURA. + * Copyright 1988-2019 Haruyasu YOSHIZAKI. + * Copyright 1988-2019 Kenji RIKITAKE. + * Copyright 2016-2019 Miran Grca. */ #include #include @@ -43,90 +43,88 @@ #include <86box/fdd_td0.h> #include <86box/fdc.h> - -#define BUFSZ 512 /* new input buffer */ -#define TD0_MAX_BUFSZ (1024UL*1024UL*4UL) +#define BUFSZ 512 /* new input buffer */ +#define TD0_MAX_BUFSZ (1024UL * 1024UL * 4UL) /* LZSS Parameters */ -#define N 4096 /* Size of string buffer */ -#define F 60 /* Size of look-ahead buffer */ -#define THRESHOLD 2 -#define NIL N /* End of tree's node */ +#define N 4096 /* Size of string buffer */ +#define F 60 /* Size of look-ahead buffer */ +#define THRESHOLD 2 +#define NIL N /* End of tree's node */ /* Huffman coding parameters */ -#define N_CHAR (256-THRESHOLD+F) /* code (= 0..N_CHAR-1) */ -#define T (N_CHAR*2-1) /* Size of table */ -#define R (T-1) /* root position */ -#define MAX_FREQ 0x8000 - /* update when cumulative frequency */ - /* reaches to this value */ +#define N_CHAR (256 - THRESHOLD + F) /* code (= 0..N_CHAR-1) */ +#define T (N_CHAR * 2 - 1) /* Size of table */ +#define R (T - 1) /* root position */ +#define MAX_FREQ 0x8000 +/* update when cumulative frequency */ +/* reaches to this value */ typedef struct { - uint16_t r, - bufcnt,bufndx,bufpos, /* string buffer */ - /* the following to allow block reads - from input in next_word() */ - ibufcnt,ibufndx; /* input buffer counters */ - uint8_t inbuf[BUFSZ]; /* input buffer */ + uint16_t r, + bufcnt, bufndx, bufpos, /* string buffer */ + /* the following to allow block reads + from input in next_word() */ + ibufcnt, ibufndx; /* input buffer counters */ + uint8_t inbuf[BUFSZ]; /* input buffer */ } tdlzhuf; typedef struct { - FILE *fdd_file; - off_t fdd_file_offset; + FILE *fdd_file; + off_t fdd_file_offset; - tdlzhuf tdctl; - uint8_t text_buf[N + F - 1]; - uint16_t freq[T + 1]; /* cumulative freq table */ + tdlzhuf tdctl; + uint8_t text_buf[N + F - 1]; + uint16_t freq[T + 1]; /* cumulative freq table */ /* * pointing parent nodes. * area [T..(T + N_CHAR - 1)] are pointers for leaves */ - int16_t prnt[T + N_CHAR]; + int16_t prnt[T + N_CHAR]; /* pointing children nodes (son[], son[] + 1)*/ - int16_t son[T]; + int16_t son[T]; - uint16_t getbuf; - uint8_t getlen; + uint16_t getbuf; + uint8_t getlen; } td0dsk_t; typedef struct { - uint8_t track; - uint8_t head; - uint8_t sector; - uint8_t size; - uint8_t flags; - uint8_t fm; - uint8_t *data; + uint8_t track; + uint8_t head; + uint8_t sector; + uint8_t size; + uint8_t flags; + uint8_t fm; + uint8_t *data; } td0_sector_t; typedef struct { - FILE *f; + FILE *f; - int tracks; - int track_width; - int sides; - uint16_t disk_flags; - uint16_t default_track_flags; - uint16_t side_flags[256][2]; - uint8_t max_sector_size; - uint8_t track_in_file[256][2]; + int tracks; + int track_width; + int sides; + uint16_t disk_flags; + uint16_t default_track_flags; + uint16_t side_flags[256][2]; + uint8_t max_sector_size; + uint8_t track_in_file[256][2]; td0_sector_t sects[256][2][256]; - uint8_t track_spt[256][2]; - uint8_t gap3_len; - uint16_t current_side_flags[2]; - int track; - int current_sector_index[2]; - uint8_t calculated_gap3_lengths[256][2]; - uint8_t xdf_ordered_pos[256][2]; - uint8_t interleave_ordered_pos[256][2]; + uint8_t track_spt[256][2]; + uint8_t gap3_len; + uint16_t current_side_flags[2]; + int track; + int current_sector_index[2]; + uint8_t calculated_gap3_lengths[256][2]; + uint8_t xdf_ordered_pos[256][2]; + uint8_t interleave_ordered_pos[256][2]; - uint8_t *imagebuf; - uint8_t *processed_buf; + uint8_t *imagebuf; + uint8_t *processed_buf; } td0_t; - /* * Tables for encoding/decoding upper 6 bits of * sliding dictionary pointer @@ -201,8 +199,7 @@ static const uint8_t d_len[256] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, }; - -static td0_t *td0[FDD_NUM]; +static td0_t *td0[FDD_NUM]; #ifdef ENABLE_TD0_LOG int td0_do_log = ENABLE_TD0_LOG; @@ -210,47 +207,43 @@ int td0_do_log = ENABLE_TD0_LOG; static void td0_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (td0_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } + if (td0_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } } #else -#define td0_log(fmt, ...) +# define td0_log(fmt, ...) #endif - static void fdd_image_read(int drive, char *buffer, uint32_t offset, uint32_t len) { td0_t *dev = td0[drive]; if (fseek(dev->f, offset, SEEK_SET) == -1) - fatal("fdd_image_read(): Error seeking to the beginning of the file\n"); + fatal("fdd_image_read(): Error seeking to the beginning of the file\n"); if (fread(buffer, 1, len, dev->f) != len) - fatal("fdd_image_read(): Error reading data\n"); + fatal("fdd_image_read(): Error reading data\n"); } - static int dsk_identify(int drive) { char header[2]; fdd_image_read(drive, header, 0, 2); - if (header[0]=='T' && header[1]=='D') - return(1); - else if (header[0]=='t' && header[1]=='d') - return(1); + if (header[0] == 'T' && header[1] == 'D') + return (1); + else if (header[0] == 't' && header[1] == 'd') + return (1); - return(0); + return (0); } - static int state_data_read(td0dsk_t *state, uint8_t *buf, uint16_t size) { @@ -259,36 +252,34 @@ state_data_read(td0dsk_t *state, uint8_t *buf, uint16_t size) fseek(state->fdd_file, 0, SEEK_END); image_size = ftell(state->fdd_file); if (size > image_size - state->fdd_file_offset) - size = (image_size - state->fdd_file_offset) & 0xffff; + size = (image_size - state->fdd_file_offset) & 0xffff; if (fseek(state->fdd_file, state->fdd_file_offset, SEEK_SET) == -1) - fatal("TD0: Failed to seek in state_data_read()\n"); + fatal("TD0: Failed to seek in state_data_read()\n"); if (fread(buf, 1, size, state->fdd_file) != size) - fatal("TD0: Error reading data in state_data_read()\n"); + fatal("TD0: Error reading data in state_data_read()\n"); state->fdd_file_offset += size; - return(size); + return (size); } - static int state_next_word(td0dsk_t *state) { if (state->tdctl.ibufndx >= state->tdctl.ibufcnt) { - state->tdctl.ibufndx = 0; - state->tdctl.ibufcnt = state_data_read(state, state->tdctl.inbuf,BUFSZ); - if (state->tdctl.ibufcnt == 0) - return(-1); + state->tdctl.ibufndx = 0; + state->tdctl.ibufcnt = state_data_read(state, state->tdctl.inbuf, BUFSZ); + if (state->tdctl.ibufcnt == 0) + return (-1); } while (state->getlen <= 8) { /* typically reads a word at a time */ - state->getbuf |= state->tdctl.inbuf[state->tdctl.ibufndx++] << (8 - state->getlen); - state->getlen += 8; + state->getbuf |= state->tdctl.inbuf[state->tdctl.ibufndx++] << (8 - state->getlen); + state->getlen += 8; } - return(0); + return (0); } - /* get one bit */ static int state_GetBit(td0dsk_t *state) @@ -296,18 +287,17 @@ state_GetBit(td0dsk_t *state) int16_t i; if (state_next_word(state) < 0) - return(-1); + return (-1); i = state->getbuf; state->getbuf <<= 1; state->getlen--; if (i < 0) - return(1); + return (1); - return(0); + return (0); } - /* get a byte */ static int state_GetByte(td0dsk_t *state) @@ -315,17 +305,16 @@ state_GetByte(td0dsk_t *state) uint16_t i; if (state_next_word(state) != 0) - return(-1); + return (-1); i = state->getbuf; state->getbuf <<= 8; state->getlen -= 8; i = i >> 8; - return((int) i); + return ((int) i); } - /* initialize freq tree */ static void state_StartHuff(td0dsk_t *state) @@ -333,65 +322,65 @@ state_StartHuff(td0dsk_t *state) int i, j; for (i = 0; i < N_CHAR; i++) { - state->freq[i] = 1; - state->son[i] = i + T; - state->prnt[i + T] = i; + state->freq[i] = 1; + state->son[i] = i + T; + state->prnt[i + T] = i; } - i = 0; j = N_CHAR; + i = 0; + j = N_CHAR; while (j <= R) { - state->freq[j] = state->freq[i] + state->freq[i + 1]; - state->son[j] = i; - state->prnt[i] = state->prnt[i + 1] = j; - i += 2; j++; + state->freq[j] = state->freq[i] + state->freq[i + 1]; + state->son[j] = i; + state->prnt[i] = state->prnt[i + 1] = j; + i += 2; + j++; } state->freq[T] = 0xffff; state->prnt[R] = 0; } - /* reconstruct freq tree */ static void state_reconst(td0dsk_t *state) { - int16_t i, j, k; + int16_t i, j, k; uint16_t f, l; /* halven cumulative freq for leaf nodes */ j = 0; for (i = 0; i < T; i++) { - if (state->son[i] >= T) { - state->freq[j] = (state->freq[i] + 1) / 2; - state->son[j] = state->son[i]; - j++; - } + if (state->son[i] >= T) { + state->freq[j] = (state->freq[i] + 1) / 2; + state->son[j] = state->son[i]; + j++; + } } /* make a tree : first, connect children nodes */ for (i = 0, j = N_CHAR; j < T; i += 2, j++) { - k = i + 1; - f = state->freq[j] = state->freq[i] + state->freq[k]; - for (k = j - 1; f < state->freq[k]; k--) {}; - k++; - l = (j - k) * 2; + k = i + 1; + f = state->freq[j] = state->freq[i] + state->freq[k]; + for (k = j - 1; f < state->freq[k]; k--) { }; + k++; + l = (j - k) * 2; - /* These *HAVE* to be memmove's as destination and source - can overlap, which memcpy can't handle. */ - memmove(&state->freq[k + 1], &state->freq[k], l); - state->freq[k] = f; - memmove(&state->son[k + 1], &state->son[k], l); - state->son[k] = i; + /* These *HAVE* to be memmove's as destination and source + can overlap, which memcpy can't handle. */ + memmove(&state->freq[k + 1], &state->freq[k], l); + state->freq[k] = f; + memmove(&state->son[k + 1], &state->son[k], l); + state->son[k] = i; } /* connect parent nodes */ for (i = 0; i < T; i++) { - if ((k = state->son[i]) >= T) - state->prnt[k] = i; - else - state->prnt[k] = state->prnt[k + 1] = i; + if ((k = state->son[i]) >= T) + state->prnt[k] = i; + else + state->prnt[k] = state->prnt[k + 1] = i; } } - /* update freq tree */ static void state_update(td0dsk_t *state, int c) @@ -399,42 +388,43 @@ state_update(td0dsk_t *state, int c) int i, j, k, l; if (state->freq[R] == MAX_FREQ) - state_reconst(state); + state_reconst(state); c = state->prnt[c + T]; /* do it until reaching the root */ do { - k = ++state->freq[c]; + k = ++state->freq[c]; - /* swap nodes to keep the tree freq-ordered */ - if (k > state->freq[l = c + 1]) { - while (k > state->freq[++l]) {}; - l--; - state->freq[c] = state->freq[l]; - state->freq[l] = k; + /* swap nodes to keep the tree freq-ordered */ + if (k > state->freq[l = c + 1]) { + while (k > state->freq[++l]) { }; + l--; + state->freq[c] = state->freq[l]; + state->freq[l] = k; - i = state->son[c]; - state->prnt[i] = l; - if (i < T) state->prnt[i + 1] = l; + i = state->son[c]; + state->prnt[i] = l; + if (i < T) + state->prnt[i + 1] = l; - j = state->son[l]; - state->son[l] = i; + j = state->son[l]; + state->son[l] = i; - state->prnt[j] = c; - if (j < T) state->prnt[j + 1] = c; - state->son[c] = j; + state->prnt[j] = c; + if (j < T) + state->prnt[j + 1] = c; + state->son[c] = j; - c = l; - } + c = l; + } } while ((c = state->prnt[c]) != 0); } - static int16_t state_DecodeChar(td0dsk_t *state) { - int ret; + int ret; uint16_t c; c = state->son[R]; @@ -445,201 +435,196 @@ state_DecodeChar(td0dsk_t *state) * else choose #(son[]+1) (input bit == 1) */ while (c < T) { - if ((ret = state_GetBit(state)) < 0) - return(-1); - c += (unsigned) ret; - c = state->son[c]; + if ((ret = state_GetBit(state)) < 0) + return (-1); + c += (unsigned) ret; + c = state->son[c]; } c -= T; state_update(state, c); - return(c); + return (c); } - static int16_t state_DecodePosition(td0dsk_t *state) { - int16_t bit; + int16_t bit; uint16_t i, j, c; /* decode upper 6 bits from given table */ if ((bit = state_GetByte(state)) < 0) - return(-1); + return (-1); i = (uint16_t) bit; - c = (uint16_t)d_code[i] << 6; + c = (uint16_t) d_code[i] << 6; j = d_len[i]; /* input lower 6 bits directly */ j -= 2; while (j--) { - if ((bit = state_GetBit(state)) < 0) - return(-1); - i = (i << 1) + bit; + if ((bit = state_GetBit(state)) < 0) + return (-1); + i = (i << 1) + bit; } - return(c | (i & 0x3f)); + return (c | (i & 0x3f)); } - /* DeCompression - split out initialization code to init_Decode() */ static void state_init_Decode(td0dsk_t *state) { int i; - state->getbuf = 0; - state->getlen = 0; - state->tdctl.ibufcnt= state->tdctl.ibufndx = 0; /* input buffer is empty */ - state->tdctl.bufcnt = 0; + state->getbuf = 0; + state->getlen = 0; + state->tdctl.ibufcnt = state->tdctl.ibufndx = 0; /* input buffer is empty */ + state->tdctl.bufcnt = 0; state_StartHuff(state); for (i = 0; i < N - F; i++) - state->text_buf[i] = ' '; + state->text_buf[i] = ' '; state->tdctl.r = N - F; } - /* Decoding/Uncompressing */ static int state_Decode(td0dsk_t *state, uint8_t *buf, int len) { int16_t c, pos; - int count; /* was an unsigned long, seems unnecessary */ + int count; /* was an unsigned long, seems unnecessary */ - for (count = 0; count < len; ) { - if (state->tdctl.bufcnt == 0) { - if ((c = state_DecodeChar(state)) < 0) - return(count); /* fatal error */ - if (c < 256) { - *(buf++) = c & 0xff; - state->text_buf[state->tdctl.r++] = c & 0xff; - state->tdctl.r &= (N - 1); - count++; - } else { - if ((pos = state_DecodePosition(state)) < 0) - return(count); /* fatal error */ - state->tdctl.bufpos = (state->tdctl.r - pos - 1) & (N - 1); - state->tdctl.bufcnt = c - 255 + THRESHOLD; - state->tdctl.bufndx = 0; - } - } else { - /* still chars from last string */ - while (state->tdctl.bufndx < state->tdctl.bufcnt && count < len) { - c = state->text_buf[(state->tdctl.bufpos + state->tdctl.bufndx) & (N - 1)]; - *(buf++) = c & 0xff; - state->tdctl.bufndx++; - state->text_buf[state->tdctl.r++] = c & 0xff; - state->tdctl.r &= (N - 1); - count++; - } + for (count = 0; count < len;) { + if (state->tdctl.bufcnt == 0) { + if ((c = state_DecodeChar(state)) < 0) + return (count); /* fatal error */ + if (c < 256) { + *(buf++) = c & 0xff; + state->text_buf[state->tdctl.r++] = c & 0xff; + state->tdctl.r &= (N - 1); + count++; + } else { + if ((pos = state_DecodePosition(state)) < 0) + return (count); /* fatal error */ + state->tdctl.bufpos = (state->tdctl.r - pos - 1) & (N - 1); + state->tdctl.bufcnt = c - 255 + THRESHOLD; + state->tdctl.bufndx = 0; + } + } else { + /* still chars from last string */ + while (state->tdctl.bufndx < state->tdctl.bufcnt && count < len) { + c = state->text_buf[(state->tdctl.bufpos + state->tdctl.bufndx) & (N - 1)]; + *(buf++) = c & 0xff; + state->tdctl.bufndx++; + state->text_buf[state->tdctl.r++] = c & 0xff; + state->tdctl.r &= (N - 1); + count++; + } - /* reset bufcnt after copy string from text_buf[] */ - if (state->tdctl.bufndx >= state->tdctl.bufcnt) - state->tdctl.bufndx = state->tdctl.bufcnt = 0; - } + /* reset bufcnt after copy string from text_buf[] */ + if (state->tdctl.bufndx >= state->tdctl.bufcnt) + state->tdctl.bufndx = state->tdctl.bufcnt = 0; + } } - return(count); /* count == len, success */ + return (count); /* count == len, success */ } - static uint32_t get_raw_tsize(int side_flags, int slower_rpm) { uint32_t size; - switch(side_flags & 0x27) { - case 0x22: - size = slower_rpm ? 5314 : 5208; - break; + switch (side_flags & 0x27) { + case 0x22: + size = slower_rpm ? 5314 : 5208; + break; - default: - case 0x02: - case 0x21: - size = slower_rpm ? 6375 : 6250; - break; + default: + case 0x02: + case 0x21: + size = slower_rpm ? 6375 : 6250; + break; - case 0x01: - size = slower_rpm ? 7650 : 7500; - break; + case 0x01: + size = slower_rpm ? 7650 : 7500; + break; - case 0x20: - size = slower_rpm ? 10629 : 10416; - break; + case 0x20: + size = slower_rpm ? 10629 : 10416; + break; - case 0x00: - size = slower_rpm ? 12750 : 12500; - break; + case 0x00: + size = slower_rpm ? 12750 : 12500; + break; - case 0x23: - size = slower_rpm ? 21258 : 20833; - break; + case 0x23: + size = slower_rpm ? 21258 : 20833; + break; - case 0x03: - size = slower_rpm ? 25500 : 25000; - break; + case 0x03: + size = slower_rpm ? 25500 : 25000; + break; - case 0x25: - size = slower_rpm ? 42517 : 41666; - break; + case 0x25: + size = slower_rpm ? 42517 : 41666; + break; - case 0x05: - size = slower_rpm ? 51000 : 50000; - break; + case 0x05: + size = slower_rpm ? 51000 : 50000; + break; } - return(size); + return (size); } - static int td0_initialize(int drive) { - td0_t *dev = td0[drive]; - uint8_t header[12]; - int fm, head, track; - int track_count = 0; - int head_count = 0; - int track_spt, track_spt_adjusted; - int offset = 0; - int density = 0; - int temp_rate = 0; + td0_t *dev = td0[drive]; + uint8_t header[12]; + int fm, head, track; + int track_count = 0; + int head_count = 0; + int track_spt, track_spt_adjusted; + int offset = 0; + int density = 0; + int temp_rate = 0; uint32_t file_size; uint16_t len, rep; td0dsk_t disk_decode; uint8_t *hs; uint16_t size; - uint8_t *dbuf = dev->processed_buf; - uint32_t total_size = 0; - uint32_t id_field = 0; - uint32_t pre_sector = 0; - int32_t track_size = 0; - int32_t raw_tsize = 0; + uint8_t *dbuf = dev->processed_buf; + uint32_t total_size = 0; + uint32_t id_field = 0; + uint32_t pre_sector = 0; + int32_t track_size = 0; + int32_t raw_tsize = 0; uint32_t minimum_gap3 = 0; uint32_t minimum_gap4 = 0; - int i, j, k; - int size_diff, gap_sum; + int i, j, k; + int size_diff, gap_sum; if (dev->f == NULL) { - td0_log("TD0: Attempted to initialize without loading a file first\n"); - return(0); + td0_log("TD0: Attempted to initialize without loading a file first\n"); + return (0); } fseek(dev->f, 0, SEEK_END); file_size = ftell(dev->f); if (file_size < 12) { - td0_log("TD0: File is too small to even contain the header\n"); - return(0); + td0_log("TD0: File is too small to even contain the header\n"); + return (0); } if (file_size > TD0_MAX_BUFSZ) { - td0_log("TD0: File exceeds the maximum size\n"); - return(0); + td0_log("TD0: File exceeds the maximum size\n"); + return (0); } fseek(dev->f, 0, SEEK_SET); @@ -647,34 +632,34 @@ td0_initialize(int drive) head_count = header[9]; if (header[0] == 't') { - td0_log("TD0: File is compressed\n"); - disk_decode.fdd_file = dev->f; - state_init_Decode(&disk_decode); - disk_decode.fdd_file_offset = 12; - state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ); + td0_log("TD0: File is compressed\n"); + disk_decode.fdd_file = dev->f; + state_init_Decode(&disk_decode); + disk_decode.fdd_file_offset = 12; + state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ); } else { - td0_log("TD0: File is uncompressed\n"); - if (fseek(dev->f, 12, SEEK_SET) == -1) - fatal("td0_initialize(): Error seeking to offet 12\n"); - if (fread(dev->imagebuf, 1, file_size - 12, dev->f) != (file_size - 12)) - fatal("td0_initialize(): Error reading image buffer\n"); + td0_log("TD0: File is uncompressed\n"); + if (fseek(dev->f, 12, SEEK_SET) == -1) + fatal("td0_initialize(): Error seeking to offet 12\n"); + if (fread(dev->imagebuf, 1, file_size - 12, dev->f) != (file_size - 12)) + fatal("td0_initialize(): Error reading image buffer\n"); } if (header[7] & 0x80) - offset = 10 + dev->imagebuf[2] + (dev->imagebuf[3] << 8); + offset = 10 + dev->imagebuf[2] + (dev->imagebuf[3] << 8); track_spt = dev->imagebuf[offset]; if (track_spt == 255) { - /* Empty file? */ - td0_log("TD0: File has no tracks\n"); - return(0); + /* Empty file? */ + td0_log("TD0: File has no tracks\n"); + return (0); } density = (header[5] >> 1) & 3; if (density == 3) { - td0_log("TD0: Unknown density\n"); - return(0); + td0_log("TD0: Unknown density\n"); + return (0); } /* @@ -683,30 +668,30 @@ td0_initialize(int drive) * from the CMOS. */ switch (header[6]) { - case 0: /* 5.25" 360k in 1.2M drive: 360 rpm - CMOS Drive type: None, value probably - reused by Teledisk */ - case 2: /* 5.25" 1.2M 360 rpm */ - case 5: /* 8"/5.25"/3.5" 1.25M 360 rpm */ - dev->default_track_flags = (density == 1) ? 0x20 : 0x21; - dev->max_sector_size = (density == 1) ? 6 : 5; /* 8192 or 4096 bytes. */ - break; + case 0: /* 5.25" 360k in 1.2M drive: 360 rpm + CMOS Drive type: None, value probably + reused by Teledisk */ + case 2: /* 5.25" 1.2M 360 rpm */ + case 5: /* 8"/5.25"/3.5" 1.25M 360 rpm */ + dev->default_track_flags = (density == 1) ? 0x20 : 0x21; + dev->max_sector_size = (density == 1) ? 6 : 5; /* 8192 or 4096 bytes. */ + break; - case 1: /* 5.25" 360k: 300 rpm */ - case 3: /* 3.5" 720k: 300 rpm */ - dev->default_track_flags = 0x02; - dev->max_sector_size = 5; /* 4096 bytes. */ - break; + case 1: /* 5.25" 360k: 300 rpm */ + case 3: /* 3.5" 720k: 300 rpm */ + dev->default_track_flags = 0x02; + dev->max_sector_size = 5; /* 4096 bytes. */ + break; - case 4: /* 3.5" 1.44M: 300 rpm */ - dev->default_track_flags = (density == 1) ? 0x00 : 0x02; - dev->max_sector_size = (density == 1) ? 6 : 5; /* 8192 or 4096 bytes. */ - break; + case 4: /* 3.5" 1.44M: 300 rpm */ + dev->default_track_flags = (density == 1) ? 0x00 : 0x02; + dev->max_sector_size = (density == 1) ? 6 : 5; /* 8192 or 4096 bytes. */ + break; - case 6: /* 3.5" 2.88M: 300 rpm */ - dev->default_track_flags = (density == 1) ? 0x00 : ((density == 2) ? 0x03 : 0x02); - dev->max_sector_size = (density == 1) ? 6 : ((density == 2) ? 7 : 5); /* 16384, 8192, or 4096 bytes. */ - break; + case 6: /* 3.5" 2.88M: 300 rpm */ + dev->default_track_flags = (density == 1) ? 0x00 : ((density == 2) ? 0x03 : 0x02); + dev->max_sector_size = (density == 1) ? 6 : ((density == 2) ? 7 : 5); /* 16384, 8192, or 4096 bytes. */ + break; } dev->disk_flags = header[5] & 0x06; @@ -714,161 +699,161 @@ td0_initialize(int drive) dev->track_width = (header[7] & 1) ^ 1; for (i = 0; i < 256; i++) { - memset(dev->side_flags[i], 0, 4); - memset(dev->track_in_file[i], 0, 2); - memset(dev->calculated_gap3_lengths[i], 0, 2); - for (j = 0; j < 2; j++) - memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); + memset(dev->side_flags[i], 0, 4); + memset(dev->track_in_file[i], 0, 2); + memset(dev->calculated_gap3_lengths[i], 0, 2); + for (j = 0; j < 2; j++) + memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); } while (track_spt != 255) { - track_spt_adjusted = track_spt; + track_spt_adjusted = track_spt; - track = dev->imagebuf[offset + 1]; - head = dev->imagebuf[offset + 2] & 1; - fm = (header[5] & 0x80) || (dev->imagebuf[offset + 2] & 0x80); /* ? */ - dev->side_flags[track][head] = dev->default_track_flags | (fm ? 0 : 8); - dev->track_in_file[track][head] = 1; - offset += 4; - track_size = fm ? 73 : 146; - if (density == 2) - id_field = fm ? 54 : 63; - else - id_field = fm ? 35 : 44; - pre_sector = id_field + (fm ? 7 : 16); + track = dev->imagebuf[offset + 1]; + head = dev->imagebuf[offset + 2] & 1; + fm = (header[5] & 0x80) || (dev->imagebuf[offset + 2] & 0x80); /* ? */ + dev->side_flags[track][head] = dev->default_track_flags | (fm ? 0 : 8); + dev->track_in_file[track][head] = 1; + offset += 4; + track_size = fm ? 73 : 146; + if (density == 2) + id_field = fm ? 54 : 63; + else + id_field = fm ? 35 : 44; + pre_sector = id_field + (fm ? 7 : 16); - for (i = 0; i < track_spt; i++) { - hs = &dev->imagebuf[offset]; - offset += 6; + for (i = 0; i < track_spt; i++) { + hs = &dev->imagebuf[offset]; + offset += 6; - dev->sects[track][head][i].track = hs[0]; - dev->sects[track][head][i].head = hs[1]; - dev->sects[track][head][i].sector = hs[2]; - dev->sects[track][head][i].size = hs[3]; - dev->sects[track][head][i].flags = hs[4]; - dev->sects[track][head][i].fm = !!fm; - dev->sects[track][head][i].data = dbuf; + dev->sects[track][head][i].track = hs[0]; + dev->sects[track][head][i].head = hs[1]; + dev->sects[track][head][i].sector = hs[2]; + dev->sects[track][head][i].size = hs[3]; + dev->sects[track][head][i].flags = hs[4]; + dev->sects[track][head][i].fm = !!fm; + dev->sects[track][head][i].data = dbuf; - size = 128 << hs[3]; - if ((total_size + size) >= TD0_MAX_BUFSZ) { - td0_log("TD0: Processed buffer overflow\n"); - return(0); - } + size = 128 << hs[3]; + if ((total_size + size) >= TD0_MAX_BUFSZ) { + td0_log("TD0: Processed buffer overflow\n"); + return (0); + } - if (hs[4] & 0x30) - memset(dbuf, (hs[4] & 0x10) ? 0xf6 : 0x00, size); - else { - offset += 3; - switch (hs[8]) { - default: - td0_log("TD0: Image uses an unsupported sector data encoding: %i\n", hs[8]); - return(0); + if (hs[4] & 0x30) + memset(dbuf, (hs[4] & 0x10) ? 0xf6 : 0x00, size); + else { + offset += 3; + switch (hs[8]) { + default: + td0_log("TD0: Image uses an unsupported sector data encoding: %i\n", hs[8]); + return (0); - case 0: - memcpy(dbuf, &dev->imagebuf[offset], size); - offset += size; - break; + case 0: + memcpy(dbuf, &dev->imagebuf[offset], size); + offset += size; + break; - case 1: - offset += 4; - k = (hs[9] + (hs[10] << 8)) * 2; - k = (k <= size) ? k : size; - for(j = 0; j < k; j += 2) { - dbuf[j] = hs[11]; - dbuf[j + 1] = hs[12]; - } - if (k < size) - memset(&(dbuf[k]), 0, size - k); - break; + case 1: + offset += 4; + k = (hs[9] + (hs[10] << 8)) * 2; + k = (k <= size) ? k : size; + for (j = 0; j < k; j += 2) { + dbuf[j] = hs[11]; + dbuf[j + 1] = hs[12]; + } + if (k < size) + memset(&(dbuf[k]), 0, size - k); + break; - case 2: - k = 0; - while (k < size) { - len = dev->imagebuf[offset]; - rep = dev->imagebuf[offset + 1]; - offset += 2; - if (! len) { - memcpy(&(dbuf[k]), &dev->imagebuf[offset], rep); - offset += rep; - k += rep; - } else { - len = (1 << len); - rep = len * rep; - rep = ((rep + k) <= size) ? rep : (size - k); - for(j = 0; j < rep; j += len) - memcpy(&(dbuf[j + k]), &dev->imagebuf[offset], len); - k += rep; - offset += len; - } - } - break; - } - } + case 2: + k = 0; + while (k < size) { + len = dev->imagebuf[offset]; + rep = dev->imagebuf[offset + 1]; + offset += 2; + if (!len) { + memcpy(&(dbuf[k]), &dev->imagebuf[offset], rep); + offset += rep; + k += rep; + } else { + len = (1 << len); + rep = len * rep; + rep = ((rep + k) <= size) ? rep : (size - k); + for (j = 0; j < rep; j += len) + memcpy(&(dbuf[j + k]), &dev->imagebuf[offset], len); + k += rep; + offset += len; + } + } + break; + } + } - dbuf += size; - total_size += size; + dbuf += size; + total_size += size; - if (hs[4] & 0x20) { - track_size += id_field; - track_spt_adjusted--; - } else if (hs[4] & 0x40) - track_size += (pre_sector - id_field + 3); - else { - if ((hs[4] & 0x02) || (hs[3] > (dev->max_sector_size - fm))) - track_size += (pre_sector + 3); - else - track_size += (pre_sector + size + 2); - } - } + if (hs[4] & 0x20) { + track_size += id_field; + track_spt_adjusted--; + } else if (hs[4] & 0x40) + track_size += (pre_sector - id_field + 3); + else { + if ((hs[4] & 0x02) || (hs[3] > (dev->max_sector_size - fm))) + track_size += (pre_sector + 3); + else + track_size += (pre_sector + size + 2); + } + } - if (track > track_count) - track_count = track; + if (track > track_count) + track_count = track; - if (track_spt != 255) { - dev->track_spt[track][head] = track_spt; + if (track_spt != 255) { + dev->track_spt[track][head] = track_spt; - if ((dev->track_spt[track][head] == 8) && (dev->sects[track][head][0].size == 3)) - dev->side_flags[track][head] = (dev->side_flags[track][head] & ~0x67) | 0x20; + if ((dev->track_spt[track][head] == 8) && (dev->sects[track][head][0].size == 3)) + dev->side_flags[track][head] = (dev->side_flags[track][head] & ~0x67) | 0x20; - raw_tsize = get_raw_tsize(dev->side_flags[track][head], 0); - minimum_gap3 = 12 * track_spt_adjusted; - size_diff = raw_tsize - track_size; - gap_sum = minimum_gap3 + minimum_gap4; - if (size_diff < gap_sum) { - /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ - raw_tsize = get_raw_tsize(dev->side_flags[track][head], 1); - /* Set disk flags so that rotation speed is 2% slower. */ - dev->disk_flags |= (3 << 5); - size_diff = raw_tsize - track_size; - if ((size_diff < gap_sum) && !fdd_get_turbo(drive)) { - /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ - td0_log("TD0: Unable to fit the %i sectors into drive %i, track %i, side %i\n", track_spt_adjusted, drive, track, head); - return 0; - } - } - dev->calculated_gap3_lengths[track][head] = (size_diff - minimum_gap4) / track_spt_adjusted; + raw_tsize = get_raw_tsize(dev->side_flags[track][head], 0); + minimum_gap3 = 12 * track_spt_adjusted; + size_diff = raw_tsize - track_size; + gap_sum = minimum_gap3 + minimum_gap4; + if (size_diff < gap_sum) { + /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ + raw_tsize = get_raw_tsize(dev->side_flags[track][head], 1); + /* Set disk flags so that rotation speed is 2% slower. */ + dev->disk_flags |= (3 << 5); + size_diff = raw_tsize - track_size; + if ((size_diff < gap_sum) && !fdd_get_turbo(drive)) { + /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ + td0_log("TD0: Unable to fit the %i sectors into drive %i, track %i, side %i\n", track_spt_adjusted, drive, track, head); + return 0; + } + } + dev->calculated_gap3_lengths[track][head] = (size_diff - minimum_gap4) / track_spt_adjusted; - track_spt = dev->imagebuf[offset]; - } + track_spt = dev->imagebuf[offset]; + } } if ((dev->disk_flags & 0x60) == 0x60) - td0_log("TD0: Disk will rotate 2% below perfect RPM\n"); + td0_log("TD0: Disk will rotate 2% below perfect RPM\n"); dev->tracks = track_count + 1; temp_rate = dev->default_track_flags & 7; if ((dev->default_track_flags & 0x27) == 0x20) - temp_rate = 4; + temp_rate = 4; dev->gap3_len = gap3_sizes[temp_rate][dev->sects[0][0][0].size][dev->track_spt[0][0]]; - if (! dev->gap3_len) - dev->gap3_len = dev->calculated_gap3_lengths[0][0]; /* If we can't determine the GAP3 length, assume the smallest one we possibly know of. */ + if (!dev->gap3_len) + dev->gap3_len = dev->calculated_gap3_lengths[0][0]; /* If we can't determine the GAP3 length, assume the smallest one we possibly know of. */ if (head_count == 2) - dev->disk_flags |= 8; /* 2 sides */ + dev->disk_flags |= 8; /* 2 sides */ if (dev->tracks <= 43) - dev->track_width &= ~1; + dev->track_width &= ~1; dev->sides = head_count; @@ -877,198 +862,192 @@ td0_initialize(int drive) td0_log("TD0: File loaded: %i tracks, %i sides, disk flags: %02X, side flags: %02X, %02X, GAP3 length: %02X\n", dev->tracks, dev->sides, dev->disk_flags, dev->current_side_flags[0], dev->current_side_flags[1], dev->gap3_len); - return(1); + return (1); } - static uint16_t disk_flags(int drive) { td0_t *dev = td0[drive]; - return(dev->disk_flags); + return (dev->disk_flags); } - static uint16_t side_flags(int drive) { - td0_t *dev = td0[drive]; - int side = 0; + td0_t *dev = td0[drive]; + int side = 0; uint16_t sflags = 0; - side = fdd_get_head(drive); + side = fdd_get_head(drive); sflags = dev->current_side_flags[side]; - return(sflags); + return (sflags); } - static void set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) { td0_t *dev = td0[drive]; - int i = 0, cyl = c; + int i = 0, cyl = c; dev->current_sector_index[side] = 0; - if (cyl != dev->track) return; + if (cyl != dev->track) + return; for (i = 0; i < dev->track_spt[cyl][side]; i++) { - if ((dev->sects[cyl][side][i].track == c) && - (dev->sects[cyl][side][i].head == h) && - (dev->sects[cyl][side][i].sector == r) && - (dev->sects[cyl][side][i].size == n)) { - dev->current_sector_index[side] = i; - } + if ((dev->sects[cyl][side][i].track == c) && (dev->sects[cyl][side][i].head == h) && (dev->sects[cyl][side][i].sector == r) && (dev->sects[cyl][side][i].size == n)) { + dev->current_sector_index[side] = i; + } } } - static uint8_t poll_read_data(int drive, int side, uint16_t pos) { td0_t *dev = td0[drive]; - return(dev->sects[dev->track][side][dev->current_sector_index[side]].data[pos]); + return (dev->sects[dev->track][side][dev->current_sector_index[side]].data[pos]); } - static int track_is_xdf(int drive, int side, int track) { - td0_t *dev = td0[drive]; + td0_t *dev = td0[drive]; uint8_t id[4] = { 0, 0, 0, 0 }; - int i, effective_sectors, xdf_sectors; - int high_sectors, low_sectors; - int max_high_id, expected_high_count, expected_low_count; + int i, effective_sectors, xdf_sectors; + int high_sectors, low_sectors; + int max_high_id, expected_high_count, expected_low_count; effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; memset(dev->xdf_ordered_pos[side], 0, 256); - if (! track) { - if ((dev->track_spt[track][side] == 16) || (dev->track_spt[track][side] == 19)) { - if (! side) { - max_high_id = (dev->track_spt[track][side] == 19) ? 0x8B : 0x88; - expected_high_count = (dev->track_spt[track][side] == 19) ? 0x0B : 0x08; - expected_low_count = 8; - } else { - max_high_id = (dev->track_spt[track][side] == 19) ? 0x93 : 0x90; - expected_high_count = (dev->track_spt[track][side] == 19) ? 0x13 : 0x10; - expected_low_count = 0; - } + if (!track) { + if ((dev->track_spt[track][side] == 16) || (dev->track_spt[track][side] == 19)) { + if (!side) { + max_high_id = (dev->track_spt[track][side] == 19) ? 0x8B : 0x88; + expected_high_count = (dev->track_spt[track][side] == 19) ? 0x0B : 0x08; + expected_low_count = 8; + } else { + max_high_id = (dev->track_spt[track][side] == 19) ? 0x93 : 0x90; + expected_high_count = (dev->track_spt[track][side] == 19) ? 0x13 : 0x10; + expected_low_count = 0; + } - for (i = 0; i < dev->track_spt[track][side]; i++) { - id[0] = dev->sects[track][side][i].track; - id[1] = dev->sects[track][side][i].head; - id[2] = dev->sects[track][side][i].sector; - id[3] = dev->sects[track][side][i].size; - if (!(id[0]) && (id[1] == side) && (id[3] == 2)) { - if ((id[2] >= 0x81) && (id[2] <= max_high_id)) { - high_sectors++; - dev->xdf_ordered_pos[id[2]][side] = i; - } + for (i = 0; i < dev->track_spt[track][side]; i++) { + id[0] = dev->sects[track][side][i].track; + id[1] = dev->sects[track][side][i].head; + id[2] = dev->sects[track][side][i].sector; + id[3] = dev->sects[track][side][i].size; + if (!(id[0]) && (id[1] == side) && (id[3] == 2)) { + if ((id[2] >= 0x81) && (id[2] <= max_high_id)) { + high_sectors++; + dev->xdf_ordered_pos[id[2]][side] = i; + } - if ((id[2] >= 0x01) && (id[2] <= 0x08)) { - low_sectors++; - dev->xdf_ordered_pos[id[2]][side] = i; - } - } - } + if ((id[2] >= 0x01) && (id[2] <= 0x08)) { + low_sectors++; + dev->xdf_ordered_pos[id[2]][side] = i; + } + } + } - if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) { - dev->current_side_flags[side] = (dev->track_spt[track][side] == 19) ? 0x08 : 0x28; - return((dev->track_spt[track][side] == 19) ? 2 : 1); - } - } + if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) { + dev->current_side_flags[side] = (dev->track_spt[track][side] == 19) ? 0x08 : 0x28; + return ((dev->track_spt[track][side] == 19) ? 2 : 1); + } + } } else { - for (i = 0; i < dev->track_spt[track][side]; i++) { - id[0] = dev->sects[track][side][i].track; - id[1] = dev->sects[track][side][i].head; - id[2] = dev->sects[track][side][i].sector; - id[3] = dev->sects[track][side][i].size; - effective_sectors++; - if ((id[0] == track) && (id[1] == side) && !(id[2]) && !(id[3])) { - effective_sectors--; - } - if ((id[0] == track) && (id[1] == side) && (id[2] == (id[3] | 0x80))) { - xdf_sectors++; - dev->xdf_ordered_pos[id[2]][side] = i; - } - } + for (i = 0; i < dev->track_spt[track][side]; i++) { + id[0] = dev->sects[track][side][i].track; + id[1] = dev->sects[track][side][i].head; + id[2] = dev->sects[track][side][i].sector; + id[3] = dev->sects[track][side][i].size; + effective_sectors++; + if ((id[0] == track) && (id[1] == side) && !(id[2]) && !(id[3])) { + effective_sectors--; + } + if ((id[0] == track) && (id[1] == side) && (id[2] == (id[3] | 0x80))) { + xdf_sectors++; + dev->xdf_ordered_pos[id[2]][side] = i; + } + } - if ((effective_sectors == 3) && (xdf_sectors == 3)) { - dev->current_side_flags[side] = 0x28; - return(1); /* 5.25" 2HD XDF */ - } + if ((effective_sectors == 3) && (xdf_sectors == 3)) { + dev->current_side_flags[side] = 0x28; + return (1); /* 5.25" 2HD XDF */ + } - if ((effective_sectors == 4) && (xdf_sectors == 4)) { - dev->current_side_flags[side] = 0x08; - return(2); /* 3.5" 2HD XDF */ - } + if ((effective_sectors == 4) && (xdf_sectors == 4)) { + dev->current_side_flags[side] = 0x08; + return (2); /* 3.5" 2HD XDF */ + } } - return(0); + return (0); } - static int track_is_interleave(int drive, int side, int track) { td0_t *dev = td0[drive]; - int i, effective_sectors; - int track_spt; + int i, effective_sectors; + int track_spt; effective_sectors = 0; for (i = 0; i < 256; i++) - dev->interleave_ordered_pos[i][side] = 0; + dev->interleave_ordered_pos[i][side] = 0; track_spt = dev->track_spt[track][side]; - if (track_spt != 21) return(0); + if (track_spt != 21) + return (0); for (i = 0; i < track_spt; i++) { - if ((dev->sects[track][side][i].track == track) && (dev->sects[track][side][i].head == side) && (dev->sects[track][side][i].sector >= 1) && (dev->sects[track][side][i].sector <= track_spt) && (dev->sects[track][side][i].size == 2)) { - effective_sectors++; - dev->interleave_ordered_pos[dev->sects[track][side][i].sector][side] = i; - } + if ((dev->sects[track][side][i].track == track) && (dev->sects[track][side][i].head == side) && (dev->sects[track][side][i].sector >= 1) && (dev->sects[track][side][i].sector <= track_spt) && (dev->sects[track][side][i].size == 2)) { + effective_sectors++; + dev->interleave_ordered_pos[dev->sects[track][side][i].sector][side] = i; + } } - if (effective_sectors == track_spt) return(1); + if (effective_sectors == track_spt) + return (1); - return(0); + return (0); } - static void td0_seek(int drive, int track) { - td0_t *dev = td0[drive]; - int side; + td0_t *dev = td0[drive]; + int side; uint8_t id[4] = { 0, 0, 0, 0 }; - int sector, current_pos; - int ssize = 512; - int track_rate = 0; - int track_gap2 = 22; - int track_gap3 = 12; - int xdf_type = 0; - int interleave_type = 0; - int is_trackx = 0; - int xdf_spt = 0; - int xdf_sector = 0; - int ordered_pos = 0; - int real_sector = 0; - int actual_sector = 0; - int fm, sector_adjusted; + int sector, current_pos; + int ssize = 512; + int track_rate = 0; + int track_gap2 = 22; + int track_gap3 = 12; + int xdf_type = 0; + int interleave_type = 0; + int is_trackx = 0; + int xdf_spt = 0; + int xdf_sector = 0; + int ordered_pos = 0; + int real_sector = 0; + int actual_sector = 0; + int fm, sector_adjusted; - if (dev->f == NULL) return; + if (dev->f == NULL) + return; if (!dev->track_width && fdd_doublestep_40(drive)) - track /= 2; + track /= 2; d86f_set_cur_track(drive, track); - is_trackx = (track == 0) ? 0 : 1; + is_trackx = (track == 0) ? 0 : 1; dev->track = track; dev->current_side_flags[0] = dev->side_flags[track][0]; @@ -1081,172 +1060,169 @@ td0_seek(int drive, int track) d86f_destroy_linked_lists(drive, 1); if (track > dev->tracks) { - d86f_zero_track(drive); - return; + d86f_zero_track(drive); + return; } for (side = 0; side < dev->sides; side++) { - track_rate = dev->current_side_flags[side] & 7; - /* Make sure 300 kbps @ 360 rpm is treated the same as 250 kbps @ 300 rpm. */ - if (!track_rate && (dev->current_side_flags[side] & 0x20)) - track_rate = 4; - if ((dev->current_side_flags[side] & 0x27) == 0x21) - track_rate = 2; - track_gap3 = gap3_sizes[track_rate][dev->sects[track][side][0].size][dev->track_spt[track][side]]; - if (! track_gap3) - track_gap3 = dev->calculated_gap3_lengths[track][side]; + track_rate = dev->current_side_flags[side] & 7; + /* Make sure 300 kbps @ 360 rpm is treated the same as 250 kbps @ 300 rpm. */ + if (!track_rate && (dev->current_side_flags[side] & 0x20)) + track_rate = 4; + if ((dev->current_side_flags[side] & 0x27) == 0x21) + track_rate = 2; + track_gap3 = gap3_sizes[track_rate][dev->sects[track][side][0].size][dev->track_spt[track][side]]; + if (!track_gap3) + track_gap3 = dev->calculated_gap3_lengths[track][side]; - track_gap2 = ((dev->current_side_flags[side] & 7) >= 3) ? 41 : 22; + track_gap2 = ((dev->current_side_flags[side] & 7) >= 3) ? 41 : 22; - xdf_type = track_is_xdf(drive, side, track); + xdf_type = track_is_xdf(drive, side, track); - interleave_type = track_is_interleave(drive, side, track); + interleave_type = track_is_interleave(drive, side, track); - current_pos = d86f_prepare_pretrack(drive, side, 0); - sector_adjusted = 0; + current_pos = d86f_prepare_pretrack(drive, side, 0); + sector_adjusted = 0; - if (! xdf_type) { - for (sector = 0; sector < dev->track_spt[track][side]; sector++) { - if (interleave_type == 0) { - real_sector = dev->sects[track][side][sector].sector; - actual_sector = sector; - } else { - real_sector = dmf_r[sector]; - actual_sector = dev->interleave_ordered_pos[real_sector][side]; - } + if (!xdf_type) { + for (sector = 0; sector < dev->track_spt[track][side]; sector++) { + if (interleave_type == 0) { + real_sector = dev->sects[track][side][sector].sector; + actual_sector = sector; + } else { + real_sector = dmf_r[sector]; + actual_sector = dev->interleave_ordered_pos[real_sector][side]; + } - id[0] = dev->sects[track][side][actual_sector].track; - id[1] = dev->sects[track][side][actual_sector].head; - id[2] = real_sector; - id[3] = dev->sects[track][side][actual_sector].size; - td0_log("track %i, side %i, %i,%i,%i,%i %i\n", track, side, id[0], id[1], id[2], id[3], dev->sects[track][side][actual_sector].flags); - fm = dev->sects[track][side][actual_sector].fm; - if (((dev->sects[track][side][actual_sector].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) - ssize = 3; - else - ssize = 128 << ((uint32_t) id[3]); - current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, dev->sects[track][side][actual_sector].flags); + id[0] = dev->sects[track][side][actual_sector].track; + id[1] = dev->sects[track][side][actual_sector].head; + id[2] = real_sector; + id[3] = dev->sects[track][side][actual_sector].size; + td0_log("track %i, side %i, %i,%i,%i,%i %i\n", track, side, id[0], id[1], id[2], id[3], dev->sects[track][side][actual_sector].flags); + fm = dev->sects[track][side][actual_sector].fm; + if (((dev->sects[track][side][actual_sector].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) + ssize = 3; + else + ssize = 128 << ((uint32_t) id[3]); + current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, dev->sects[track][side][actual_sector].flags); - if (sector_adjusted == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + if (sector_adjusted == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - if (!(dev->sects[track][side][actual_sector].flags & 0x40)) - sector_adjusted++; - } - } else { - xdf_type--; - xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; - for (sector = 0; sector < xdf_spt; sector++) { - xdf_sector = (side * xdf_spt) + sector; - id[0] = track; - id[1] = side; - id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; - id[3] = is_trackx ? (id[2] & 7) : 2; - ordered_pos = dev->xdf_ordered_pos[id[2]][side]; - fm = dev->sects[track][side][ordered_pos].fm; - if (((dev->sects[track][side][ordered_pos].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) - ssize = 3; - else - ssize = 128 << ((uint32_t) id[3]); - if (is_trackx) - current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags); - else - current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags); + if (!(dev->sects[track][side][actual_sector].flags & 0x40)) + sector_adjusted++; + } + } else { + xdf_type--; + xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; + for (sector = 0; sector < xdf_spt; sector++) { + xdf_sector = (side * xdf_spt) + sector; + id[0] = track; + id[1] = side; + id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; + id[3] = is_trackx ? (id[2] & 7) : 2; + ordered_pos = dev->xdf_ordered_pos[id[2]][side]; + fm = dev->sects[track][side][ordered_pos].fm; + if (((dev->sects[track][side][ordered_pos].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) + ssize = 3; + else + ssize = 128 << ((uint32_t) id[3]); + if (is_trackx) + current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags); + else + current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags); - if (sector_adjusted == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + if (sector_adjusted == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - if (!(dev->sects[track][side][ordered_pos].flags & 0x40)) - sector_adjusted++; - } - } + if (!(dev->sects[track][side][ordered_pos].flags & 0x40)) + sector_adjusted++; + } + } } } - void td0_init(void) { memset(td0, 0x00, sizeof(td0)); } - void td0_abort(int drive) { td0_t *dev = td0[drive]; if (dev->imagebuf) - free(dev->imagebuf); + free(dev->imagebuf); if (dev->processed_buf) - free(dev->processed_buf); + free(dev->processed_buf); if (dev->f) - fclose(dev->f); + fclose(dev->f); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); td0[drive] = NULL; } - void td0_load(int drive, char *fn) { - td0_t *dev; + td0_t *dev; uint32_t i; d86f_unregister(drive); writeprot[drive] = 1; - dev = (td0_t *)malloc(sizeof(td0_t)); + dev = (td0_t *) malloc(sizeof(td0_t)); memset(dev, 0x00, sizeof(td0_t)); td0[drive] = dev; dev->f = plat_fopen(fn, "rb"); if (dev->f == NULL) { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; } fwriteprot[drive] = writeprot[drive]; - if (! dsk_identify(drive)) { - td0_log("TD0: Not a valid Teledisk image\n"); - td0_abort(drive); - return; + if (!dsk_identify(drive)) { + td0_log("TD0: Not a valid Teledisk image\n"); + td0_abort(drive); + return; } else { - td0_log("TD0: Valid Teledisk image\n"); + td0_log("TD0: Valid Teledisk image\n"); } /* Allocate the processing buffers. */ - i = 1024UL * 1024UL * 4UL; - dev->imagebuf = (uint8_t *)malloc(i); + i = 1024UL * 1024UL * 4UL; + dev->imagebuf = (uint8_t *) malloc(i); memset(dev->imagebuf, 0x00, i); - dev->processed_buf = (uint8_t *)malloc(i); + dev->processed_buf = (uint8_t *) malloc(i); memset(dev->processed_buf, 0x00, i); - if (! td0_initialize(drive)) { - td0_log("TD0: Failed to initialize\n"); - td0_abort(drive); - return; + if (!td0_initialize(drive)) { + td0_log("TD0: Failed to initialize\n"); + td0_abort(drive); + return; } else { - td0_log("TD0: Initialized successfully\n"); + td0_log("TD0: Initialized successfully\n"); } /* Attach this format to the D86F engine. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = side_flags; - d86f_handler[drive].writeback = null_writeback; - d86f_handler[drive].set_sector = set_sector; - d86f_handler[drive].read_data = poll_read_data; - d86f_handler[drive].write_data = null_write_data; + d86f_handler[drive].disk_flags = disk_flags; + d86f_handler[drive].side_flags = side_flags; + d86f_handler[drive].writeback = null_writeback; + d86f_handler[drive].set_sector = set_sector; + d86f_handler[drive].read_data = poll_read_data; + d86f_handler[drive].write_data = null_write_data; d86f_handler[drive].format_conditions = null_format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; + d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + d86f_handler[drive].index_hole_pos = null_index_hole_pos; + d86f_handler[drive].get_raw_size = common_get_raw_size; + d86f_handler[drive].check_crc = 1; d86f_set_version(drive, 0x0063); drives[drive].seek = td0_seek; @@ -1254,39 +1230,39 @@ td0_load(int drive, char *fn) d86f_common_handlers(drive); } - void td0_close(int drive) { td0_t *dev = td0[drive]; - int i, j, k; + int i, j, k; - if (dev == NULL) return; + if (dev == NULL) + return; d86f_unregister(drive); if (dev->imagebuf) - free(dev->imagebuf); + free(dev->imagebuf); if (dev->processed_buf) - free(dev->processed_buf); + free(dev->processed_buf); for (i = 0; i < 256; i++) { - for (j = 0; j < 2; j++) { - for (k = 0; k < 256; k++) - dev->sects[i][j][k].data = NULL; - } + for (j = 0; j < 2; j++) { + for (k = 0; k < 256; k++) + dev->sects[i][j][k].data = NULL; + } } for (i = 0; i < 256; i++) { - memset(dev->side_flags[i], 0, 4); - memset(dev->track_in_file[i], 0, 2); - memset(dev->calculated_gap3_lengths[i], 0, 2); - for (j = 0; j < 2; j++) - memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); + memset(dev->side_flags[i], 0, 4); + memset(dev->track_in_file[i], 0, 2); + memset(dev->calculated_gap3_lengths[i], 0, 2); + for (j = 0; j < 2; j++) + memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); } if (dev->f != NULL) - fclose(dev->f); + fclose(dev->f); /* Release resources. */ free(dev); diff --git a/src/floppy/fdi2raw.c b/src/floppy/fdi2raw.c index daebebf98..b367db5c1 100644 --- a/src/floppy/fdi2raw.c +++ b/src/floppy/fdi2raw.c @@ -1,26 +1,26 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * FDI to raw bit stream converter - * FDI format created by Vincent "ApH" Joguin - * Tiny changes - function type fixes, multiple drives, - * addition of get_last_head and C++ callability by Thomas - * Harte. + * FDI to raw bit stream converter + * FDI format created by Vincent "ApH" Joguin + * Tiny changes - function type fixes, multiple drives, + * addition of get_last_head and C++ callability by Thomas + * Harte. * * * - * Authors: Toni Wilen, - * and Vincent Joguin, - * Thomas Harte, + * Authors: Toni Wilen, + * and Vincent Joguin, + * Thomas Harte, * - * Copyright 2001-2004 Toni Wilen. - * Copyright 2001-2004 Vincent Joguin. - * Copyright 2001 Thomas Harte. + * Copyright 2001-2004 Toni Wilen. + * Copyright 2001-2004 Vincent Joguin. + * Copyright 2001 Thomas Harte. */ #define STATIC_INLINE #include diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index ee78c2650..5ed136de5 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(game OBJECT gameport.c joystick_standard.c diff --git a/src/game/gameport.c b/src/game/gameport.c index 44153eff4..ab8422070 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of a generic Game Port. + * Implementation of a generic Game Port. * * * - * Authors: Miran Grca, - * Sarah Walker, - * RichardG, + * Authors: Miran Grca, + * Sarah Walker, + * RichardG, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * Copyright 2021 RichardG. + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2021 RichardG. */ #include #include @@ -116,7 +116,7 @@ static uint8_t gameport_pnp_rom[] = { static const isapnp_device_config_t gameport_pnp_defaults[] = { {.activate = 1, .io = { - { .base = 0x200 }, + { .base = 0x200 }, }} }; @@ -642,7 +642,7 @@ static const device_config_t tmacm_config[] = { } }, { "", "", -1 } -// clang-format on + // clang-format on }; const device_t gameport_tm_acm_device = { diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 2a6c52a7d..0741e0360 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -128,7 +128,7 @@ const joystick_if_t joystick_ch_flightstick_pro = { .button_count = 4, .pov_count = 1, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis", "Throttle" }, + .axis_names = { "X axis", "Y axis", "Throttle" }, .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { "POV"} + .pov_names = { "POV" } }; diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index fa3b3e2e5..71c354945 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -251,9 +251,9 @@ const joystick_if_t joystick_2axis_2button = { .button_count = 2, .pov_count = 0, .max_joysticks = 2, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } }; const joystick_if_t joystick_2axis_4button = { @@ -269,9 +269,9 @@ const joystick_if_t joystick_2axis_4button = { .button_count = 4, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } }; const joystick_if_t joystick_3axis_2button = { @@ -287,9 +287,9 @@ const joystick_if_t joystick_3axis_2button = { .button_count = 2, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis", "Z axis" }, - .button_names = { "Button 1", "Button 2" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis", "Z axis" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } }; const joystick_if_t joystick_3axis_4button = { @@ -305,9 +305,9 @@ const joystick_if_t joystick_3axis_4button = { .button_count = 4, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis", "Z axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis", "Z axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } }; const joystick_if_t joystick_4axis_4button = { @@ -323,9 +323,9 @@ const joystick_if_t joystick_4axis_4button = { .button_count = 4, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis", "Z axis", "zX axis" }, + .axis_names = { "X axis", "Y axis", "Z axis", "zX axis" }, .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { NULL } + .pov_names = { NULL } }; const joystick_if_t joystick_2axis_6button = { @@ -341,9 +341,9 @@ const joystick_if_t joystick_2axis_6button = { .button_count = 6, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6" }, + .pov_names = { NULL } }; const joystick_if_t joystick_2axis_8button = { @@ -359,7 +359,7 @@ const joystick_if_t joystick_2axis_8button = { .button_count = 8, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8" }, + .pov_names = { NULL } }; diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index 8f4c804e2..647ca6a74 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -266,7 +266,7 @@ const joystick_if_t joystick_sw_pad = { .button_count = 10, .pov_count = 0, .max_joysticks = 4, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M" }, + .pov_names = { NULL } }; diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index 63ebdbda8..4364a432f 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -128,7 +128,7 @@ const joystick_if_t joystick_tm_fcs = { .button_count = 4, .pov_count = 1, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { "POV"} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { "POV" } }; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 961930081..1db37f1a4 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Main include file for the application. + * Main include file for the application. * * * - * Authors: Miran Grca, - *f Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2021 Laci bá' + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2021 Laci bá' */ #ifndef EMU_86BOX_H #define EMU_86BOX_H @@ -162,7 +162,7 @@ extern void set_screen_size_monitor(int x, int y, int monitor_index); extern void reset_screen_size(void); extern void reset_screen_size_monitor(int monitor_index); extern void set_screen_size_natural(void); -extern void update_mouse_msg(); +extern void update_mouse_msg(void); #if 0 extern void pc_reload(wchar_t *fn); #endif diff --git a/src/include/86box/bswap.h b/src/include/86box/bswap.h index b943dd2d8..22d25cf4a 100644 --- a/src/include/86box/bswap.h +++ b/src/include/86box/bswap.h @@ -36,12 +36,12 @@ */ #ifndef BSWAP_H -# define BSWAP_H +#define BSWAP_H #include #ifdef HAVE_BYTESWAP_H -#include +# include #else # define bswap_16(x) \ ( \ @@ -73,6 +73,7 @@ ) #endif /*HAVE_BYTESWAP_H*/ +#if __GNUC__ >= 10 #if defined __has_builtin && __has_builtin(__builtin_bswap16) #define bswap16(x) __builtin_bswap16(x) #else @@ -80,83 +81,111 @@ static __inline uint16_t bswap16(uint16_t x) { return bswap_16(x); } +# endif +#else +static __inline uint16_t +bswap16(uint16_t x) +{ + return bswap_16(x); +} #endif -#if defined __has_builtin && __has_builtin(__builtin_bswap32) -#define bswap32(x) __builtin_bswap32(x) +#if __GNUC__ >= 10 +# if defined __has_builtin && __has_builtin(__builtin_bswap32) +# define bswap32(x) __builtin_bswap32(x) +# else +static __inline uint32_t +bswap32(uint32_t x) +{ + return bswap_32(x); +} +# endif #else -static __inline uint32_t bswap32(uint32_t x) +static __inline uint32_t +bswap32(uint32_t x) { return bswap_32(x); } #endif -#if defined __has_builtin && __has_builtin(__builtin_bswap64) -#define bswap64(x) __builtin_bswap64(x) +#if __GNUC__ >= 10 +# if defined __has_builtin && __has_builtin(__builtin_bswap64) +# define bswap64(x) __builtin_bswap64(x) +# else +static __inline uint64_t +bswap64(uint64_t x) +{ + return bswap_64(x); +} +# endif #else -static __inline uint64_t bswap64(uint64_t x) +static __inline uint64_t +bswap64(uint64_t x) { return bswap_64(x); } #endif -static __inline void bswap16s(uint16_t *s) +static __inline void +bswap16s(uint16_t *s) { *s = bswap16(*s); } -static __inline void bswap32s(uint32_t *s) +static __inline void +bswap32s(uint32_t *s) { *s = bswap32(*s); } -static __inline void bswap64s(uint64_t *s) +static __inline void +bswap64s(uint64_t *s) { *s = bswap64(*s); } #if defined(WORDS_BIGENDIAN) -# define be_bswap(v, size) (v) -# define le_bswap(v, size) bswap ## size(v) -# define be_bswaps(v, size) -# define le_bswaps(p, size) *p = bswap ## size(*p); +# define be_bswap(v, size) (v) +# define le_bswap(v, size) bswap##size(v) +# define be_bswaps(v, size) +# define le_bswaps(p, size) *p = bswap##size(*p); #else -# define le_bswap(v, size) (v) -# define be_bswap(v, size) bswap ## size(v) -# define le_bswaps(v, size) -# define be_bswaps(p, size) *p = bswap ## size(*p); +# define le_bswap(v, size) (v) +# define be_bswap(v, size) bswap##size(v) +# define le_bswaps(v, size) +# define be_bswaps(p, size) *p = bswap##size(*p); #endif -#define CPU_CONVERT(endian, size, type)\ -static __inline type endian ## size ## _to_cpu(type v)\ -{\ - return endian ## _bswap(v, size);\ -}\ -\ -static __inline type cpu_to_ ## endian ## size(type v)\ -{\ - return endian ## _bswap(v, size);\ -}\ -\ -static __inline void endian ## size ## _to_cpus(type *p)\ -{\ - endian ## _bswaps(p, size)\ -}\ -\ -static __inline void cpu_to_ ## endian ## size ## s(type *p)\ -{\ - endian ## _bswaps(p, size)\ -}\ -\ -static __inline type endian ## size ## _to_cpup(const type *p)\ -{\ - return endian ## size ## _to_cpu(*p);\ -}\ -\ -static __inline void cpu_to_ ## endian ## size ## w(type *p, type v)\ -{\ - *p = cpu_to_ ## endian ## size(v);\ -} +#define CPU_CONVERT(endian, size, type) \ + static __inline type endian##size##_to_cpu(type v) \ + { \ + return endian##_bswap(v, size); \ + } \ + \ + static __inline type cpu_to_##endian##size(type v) \ + { \ + return endian##_bswap(v, size); \ + } \ + \ + static __inline void endian##size##_to_cpus(type *p) \ + { \ + endian##_bswaps(p, size) \ + } \ + \ + static __inline void cpu_to_##endian##size##s(type *p) \ + { \ + endian##_bswaps(p, size) \ + } \ + \ + static __inline type endian##size##_to_cpup(const type *p) \ + { \ + return endian##size##_to_cpu(*p); \ + } \ + \ + static __inline void cpu_to_##endian##size##w(type *p, type v) \ + { \ + *p = cpu_to_##endian##size(v); \ + } CPU_CONVERT(be, 16, uint16_t) CPU_CONVERT(be, 32, uint32_t) @@ -170,27 +199,29 @@ CPU_CONVERT(le, 64, uint64_t) #if defined(__i386__) || defined(__powerpc__) -#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v) -#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v) -#define le16_to_cpupu(p) le16_to_cpup(p) -#define le32_to_cpupu(p) le32_to_cpup(p) +# define cpu_to_le16wu(p, v) cpu_to_le16w(p, v) +# define cpu_to_le32wu(p, v) cpu_to_le32w(p, v) +# define le16_to_cpupu(p) le16_to_cpup(p) +# define le32_to_cpupu(p) le32_to_cpup(p) -#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v) -#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v) +# define cpu_to_be16wu(p, v) cpu_to_be16w(p, v) +# define cpu_to_be32wu(p, v) cpu_to_be32w(p, v) #else -static __inline void cpu_to_le16wu(uint16_t *p, uint16_t v) +static __inline void +cpu_to_le16wu(uint16_t *p, uint16_t v) { - uint8_t *p1 = (uint8_t *)p; + uint8_t *p1 = (uint8_t *) p; p1[0] = v & 0xff; p1[1] = v >> 8; } -static __inline void cpu_to_le32wu(uint32_t *p, uint32_t v) +static __inline void +cpu_to_le32wu(uint32_t *p, uint32_t v) { - uint8_t *p1 = (uint8_t *)p; + uint8_t *p1 = (uint8_t *) p; p1[0] = v; p1[1] = v >> 8; @@ -198,29 +229,33 @@ static __inline void cpu_to_le32wu(uint32_t *p, uint32_t v) p1[3] = v >> 24; } -static __inline uint16_t le16_to_cpupu(const uint16_t *p) +static __inline uint16_t +le16_to_cpupu(const uint16_t *p) { - const uint8_t *p1 = (const uint8_t *)p; + const uint8_t *p1 = (const uint8_t *) p; return p1[0] | (p1[1] << 8); } -static __inline uint32_t le32_to_cpupu(const uint32_t *p) +static __inline uint32_t +le32_to_cpupu(const uint32_t *p) { - const uint8_t *p1 = (const uint8_t *)p; + const uint8_t *p1 = (const uint8_t *) p; return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24); } -static __inline void cpu_to_be16wu(uint16_t *p, uint16_t v) +static __inline void +cpu_to_be16wu(uint16_t *p, uint16_t v) { - uint8_t *p1 = (uint8_t *)p; + uint8_t *p1 = (uint8_t *) p; p1[0] = v >> 8; p1[1] = v & 0xff; } -static __inline void cpu_to_be32wu(uint32_t *p, uint32_t v) +static __inline void +cpu_to_be32wu(uint32_t *p, uint32_t v) { - uint8_t *p1 = (uint8_t *)p; + uint8_t *p1 = (uint8_t *) p; p1[0] = v >> 24; p1[1] = v >> 16; @@ -231,9 +266,9 @@ static __inline void cpu_to_be32wu(uint32_t *p, uint32_t v) #endif #ifdef WORDS_BIGENDIAN -#define cpu_to_32wu cpu_to_be32wu +# define cpu_to_32wu cpu_to_be32wu #else -#define cpu_to_32wu cpu_to_le32wu +# define cpu_to_32wu cpu_to_le32wu #endif #undef le_bswap diff --git a/src/include/86box/config.h b/src/include/86box/config.h index 1cddddaab..9946a0da3 100644 --- a/src/include/86box/config.h +++ b/src/include/86box/config.h @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Configuration file handler header. + * Configuration file handler header. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Overdoze, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Overdoze, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. */ #ifndef EMU_CONFIG_H #define EMU_CONFIG_H diff --git a/src/include/86box/discord.h b/src/include/86box/discord.h index f04370143..9a1467e08 100644 --- a/src/include/86box/discord.h +++ b/src/include/86box/discord.h @@ -23,11 +23,11 @@ extern "C" { extern int discord_loaded; -extern int discord_load(); -extern void discord_init(); -extern void discord_close(); +extern int discord_load(void); +extern void discord_init(void); +extern void discord_close(void); extern void discord_update_activity(int paused); -extern void discord_run_callbacks(); +extern void discord_run_callbacks(void); #ifdef __cplusplus } diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 355d19155..ec3136baa 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the NEC uPD-765 and compatible floppy disk - * controller. + * Implementation of the NEC uPD-765 and compatible floppy disk + * controller. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2018-2020 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2018-2020 Fred N. van Kempen. */ #ifndef EMU_FDC_H #define EMU_FDC_H @@ -40,18 +40,18 @@ extern int fdc_type; #define FDC_QUATERNARY_IRQ 6 #define FDC_QUATERNARY_DMA 2 -#define FDC_FLAG_PCJR 0x01 /* PCjr */ -#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ -#define FDC_FLAG_AT 0x04 /* AT+, PS/x */ -#define FDC_FLAG_PS1 0x08 /* PS/1, PS/2 ISA */ -#define FDC_FLAG_SUPERIO 0x10 /* Super I/O chips */ -#define FDC_FLAG_START_RWC_1 0x20 /* W83877F, W83977F */ -#define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */ -#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ -#define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ -#define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ -#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ -#define FDC_FLAG_ALI 0x800 /* ALi M512x / M1543C */ +#define FDC_FLAG_PCJR 0x01 /* PCjr */ +#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ +#define FDC_FLAG_AT 0x04 /* AT+, PS/x */ +#define FDC_FLAG_PS1 0x08 /* PS/1, PS/2 ISA */ +#define FDC_FLAG_SUPERIO 0x10 /* Super I/O chips */ +#define FDC_FLAG_START_RWC_1 0x20 /* W83877F, W83977F */ +#define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */ +#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ +#define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ +#define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ +#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ +#define FDC_FLAG_ALI 0x800 /* ALi M512x / M1543C */ #define FDC_FLAG_SEC 0x1000 /* Is Secondary */ typedef struct { diff --git a/src/include/86box/fdd.h b/src/include/86box/fdd.h index 5d8da47a0..f612466b3 100644 --- a/src/include/86box/fdd.h +++ b/src/include/86box/fdd.h @@ -1,29 +1,29 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Definitions for the floppy drive emulation. + * Definitions for the floppy drive emulation. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2018 Fred N. van Kempen. */ #ifndef EMU_FDD_H #define EMU_FDD_H -#define FDD_NUM 4 -#define FLOPPY_IMAGE_HISTORY 4 -#define SEEK_RECALIBRATE -999 +#define FDD_NUM 4 +#define FLOPPY_IMAGE_HISTORY 4 +#define SEEK_RECALIBRATE -999 #ifdef __cplusplus extern "C" { @@ -42,9 +42,7 @@ extern int fdd_can_read_medium(int drive); extern int fdd_doublestep_40(int drive); extern int fdd_is_525(int drive); extern int fdd_is_dd(int drive); -#if 0 extern int fdd_is_hd(int drive); -#endif extern int fdd_is_ed(int drive); extern int fdd_is_double_sided(int drive); extern void fdd_set_head(int drive, int head); @@ -87,7 +85,7 @@ typedef struct { extern DRIVE drives[FDD_NUM]; extern char floppyfns[FDD_NUM][512]; -extern char *fdd_image_history[FDD_NUM][FLOPPY_IMAGE_HISTORY]; +extern char *fdd_image_history[FDD_NUM][FLOPPY_IMAGE_HISTORY]; extern pc_timer_t fdd_poll_time[FDD_NUM]; extern int ui_writeprot[FDD_NUM]; diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 8ef2933ad..68b75b97b 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Definitions for the common disk controller handler. + * Definitions for the common disk controller handler. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #ifndef EMU_HDC_H #define EMU_HDC_H @@ -28,21 +28,24 @@ * least 7 devices, with each device being \ * able to support 8 units, but hey... */ +#define HDC_NONE 0 +#define HDC_INTERNAL 1 + extern int hdc_current; -extern const device_t st506_xt_xebec_device; /* st506_xt_xebec */ -extern const device_t st506_xt_dtc5150x_device; /* st506_xt_dtc */ -extern const device_t st506_xt_st11_m_device; /* st506_xt_st11_m */ -extern const device_t st506_xt_st11_r_device; /* st506_xt_st11_m */ -extern const device_t st506_xt_wd1002a_wx1_device; /* st506_xt_wd1002a_wx1 */ -extern const device_t st506_xt_wd1002a_wx1_nobios_device; /* st506_xt_wd1002a_wx1 */ -extern const device_t st506_xt_wd1002a_27x_device; /* st506_xt_wd1002a_27x */ -extern const device_t st506_at_wd1003_device; /* st506_at_wd1003 */ -extern const device_t st506_xt_wd1004a_wx1_device; /* st506_xt_wd1004a_wx1 */ -extern const device_t st506_xt_wd1004_27x_device; /* st506_xt_wd1004_27x */ -extern const device_t st506_xt_wd1004a_27x_device; /* st506_xt_wd1004a_27x */ -extern const device_t st506_xt_victor_v86p_device; /* st506_xt_victor_v86p */ -extern const device_t st506_xt_toshiba_t1200_device; /* st506_xt_toshiba_t1200 */ +extern const device_t st506_xt_xebec_device; /* st506_xt_xebec */ +extern const device_t st506_xt_dtc5150x_device; /* st506_xt_dtc */ +extern const device_t st506_xt_st11_m_device; /* st506_xt_st11_m */ +extern const device_t st506_xt_st11_r_device; /* st506_xt_st11_m */ +extern const device_t st506_xt_wd1002a_wx1_device; /* st506_xt_wd1002a_wx1 */ +extern const device_t st506_xt_wd1002a_wx1_nobios_device; /* st506_xt_wd1002a_wx1 */ +extern const device_t st506_xt_wd1002a_27x_device; /* st506_xt_wd1002a_27x */ +extern const device_t st506_at_wd1003_device; /* st506_at_wd1003 */ +extern const device_t st506_xt_wd1004a_wx1_device; /* st506_xt_wd1004a_wx1 */ +extern const device_t st506_xt_wd1004_27x_device; /* st506_xt_wd1004_27x */ +extern const device_t st506_xt_wd1004a_27x_device; /* st506_xt_wd1004a_27x */ +extern const device_t st506_xt_victor_v86p_device; /* st506_xt_victor_v86p */ +extern const device_t st506_xt_toshiba_t1200_device; /* st506_xt_toshiba_t1200 */ extern const device_t esdi_at_wd1007vse1_device; /* esdi_at */ extern const device_t esdi_ps2_device; /* esdi_mca */ diff --git a/src/include/86box/hdd.h b/src/include/86box/hdd.h index d993d5c32..abb2aa388 100644 --- a/src/include/86box/hdd.h +++ b/src/include/86box/hdd.h @@ -18,7 +18,14 @@ #ifndef EMU_HDD_H #define EMU_HDD_H -#define HDD_NUM 88 /* total of 88 images supported */ +#define IMG_FMT_RAW 0 +#define IMG_FMT_HDI 1 +#define IMG_FMT_HDX 2 +#define IMG_FMT_VHD_FIXED 3 +#define IMG_FMT_VHD_DYNAMIC 4 +#define IMG_FMT_VHD_DIFF 5 + +#define HDD_NUM 88 /* total of 88 images supported */ /* Hard Disk bus types. */ #if 0 @@ -206,7 +213,7 @@ extern int image_is_vhd(const char *s, int check_signature); extern double hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len); extern double hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len); extern double hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time); -int hdd_preset_get_num(); +int hdd_preset_get_num(void); const char *hdd_preset_getname(int preset); extern const char *hdd_preset_get_internal_name(int preset); extern int hdd_preset_get_from_internal_name(char *s); diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index a752b1689..e0410b3a0 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -38,7 +38,7 @@ typedef struct { } lm75_t; /* hwm.c */ -extern uint16_t hwm_get_vcore(); +extern uint16_t hwm_get_vcore(void); /* hwm_lm75.c */ extern void lm75_remap(lm75_t *dev, uint8_t addr); diff --git a/src/include/86box/i2c.h b/src/include/86box/i2c.h index 545f2b9ed..071e57729 100644 --- a/src/include/86box/i2c.h +++ b/src/include/86box/i2c.h @@ -62,6 +62,6 @@ extern void i2c_gpio_close(void *dev_handle); extern void i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda); extern uint8_t i2c_gpio_get_scl(void *dev_handle); extern uint8_t i2c_gpio_get_sda(void *dev_handle); -extern void *i2c_gpio_get_bus(); +extern void *i2c_gpio_get_bus(void *dev_handle); #endif /*EMU_I2C_H*/ diff --git a/src/include/86box/i8080.h b/src/include/86box/i8080.h index 05d227da8..9f85a85c0 100644 --- a/src/include/86box/i8080.h +++ b/src/include/86box/i8080.h @@ -15,42 +15,46 @@ #include -typedef struct i8080 -{ - union { +typedef struct i8080 { + union { uint16_t af; /* Intended in case we also go for μPD9002 emulation, which also has a Z80 emulation mode. */ - struct { uint8_t a, flags; }; + struct { + uint8_t a, flags; + }; }; - union - { + union { uint16_t bc; - struct { uint8_t b, c; }; + struct { + uint8_t b, c; + }; }; - union - { + union { uint16_t de; - struct { uint8_t d, e; }; + struct { + uint8_t d, e; + }; }; - union - { + union { uint16_t hl; - struct { uint8_t h, l; }; + struct { + uint8_t h, l; + }; }; - uint16_t pc, sp; - uint16_t oldpc, ei; - uint32_t pmembase, dmembase; /* Base from where i8080 starts. */ - uint8_t emulated; /* 0 = not emulated, use separate registers, 1 = emulated, use x86 registers. */ - uint16_t* cpu_flags; + uint16_t pc, sp; + uint16_t oldpc, ei; + uint32_t pmembase, dmembase; /* Base from where i8080 starts. */ + uint8_t emulated; /* 0 = not emulated, use separate registers, 1 = emulated, use x86 registers. */ + uint16_t *cpu_flags; void (*writemembyte)(uint32_t, uint8_t); uint8_t (*readmembyte)(uint32_t); - void (*startclock)(); - void (*endclock)(); - void (*checkinterrupts)(); - uint8_t (*fetchinstruction)(); + void (*startclock)(void); + void (*endclock)(void); + void (*checkinterrupts)(void); + uint8_t (*fetchinstruction)(void *); } i8080; -#define C_FLAG_I8080 (1 << 0) -#define P_FLAG_I8080 (1 << 2) +#define C_FLAG_I8080 (1 << 0) +#define P_FLAG_I8080 (1 << 2) #define AC_FLAG_I8080 (1 << 4) -#define Z_FLAG_I8080 (1 << 6) -#define S_FLAG_I8080 (1 << 7) +#define Z_FLAG_I8080 (1 << 6) +#define S_FLAG_I8080 (1 << 7) diff --git a/src/include/86box/ini.h b/src/include/86box/ini.h index 43b71f357..d754d645b 100644 --- a/src/include/86box/ini.h +++ b/src/include/86box/ini.h @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Configuration file handler header. + * Configuration file handler header. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Overdoze, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Overdoze, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016,2017 Miran Grca. * */ #ifndef EMU_INI_H @@ -48,7 +48,7 @@ extern void ini_section_set_double(ini_section_t section, char *name, double extern void ini_section_set_hex16(ini_section_t section, char *name, int val); extern void ini_section_set_hex20(ini_section_t section, char *name, int val); extern void ini_section_set_mac(ini_section_t section, char *name, int val); -extern void ini_section_set_string(ini_section_t section, char *name, char *val); +extern void ini_section_set_string(ini_section_t section, const char *name, const char *val); extern void ini_section_set_wstring(ini_section_t section, char *name, wchar_t *val); #define ini_delete_var(ini, head, name) ini_section_delete_var(ini_find_section(ini, head), name) diff --git a/src/include/86box/language.h b/src/include/86box/language.h index 6c7ad728f..90bfecc06 100644 --- a/src/include/86box/language.h +++ b/src/include/86box/language.h @@ -15,126 +15,143 @@ * Author: Fred N. van Kempen, * * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2022 Jasmine Iwanek. */ #ifndef LANG_UAGE_H #define LANG_UAGE_H /* String IDs. */ -#define IDS_STRINGS 2048 // "86Box" -#define IDS_2049 2049 // "Error" -#define IDS_2050 2050 // "Fatal error" -#define IDS_2051 2051 // " - PAUSED" -#define IDS_2052 2052 // "Press Ctrl+Alt+PgDn..." -#define IDS_2053 2053 // "Speed" -#define IDS_2054 2054 // "ZIP %i (%03i): %ls" -#define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2056 2056 // "No usable ROM images found!" -#define IDS_2057 2057 // "(empty)" -#define IDS_2058 2058 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2059 2059 // "(Turbo)" -#define IDS_2060 2060 // "On" -#define IDS_2061 2061 // "Off" -#define IDS_2062 2062 // "All floppy images (*.DSK..." -#define IDS_2063 2063 // "Machine ""%hs"" is not..." -#define IDS_2064 2064 // "Video card ""%hs"" is not..." -#define IDS_2065 2065 // "Machine" -#define IDS_2066 2066 // "Display" -#define IDS_2067 2067 // "Input devices" -#define IDS_2068 2068 // "Sound" -#define IDS_2069 2069 // "Network" -#define IDS_2070 2070 // "Ports (COM & LPT)" -#define IDS_2071 2071 // "Storage controllers" -#define IDS_2072 2072 // "Hard disks" -#define IDS_2073 2073 // "Floppy and CD-ROM drives" -#define IDS_2074 2074 // "Other removable devices" -#define IDS_2075 2075 // "Other peripherals" -#define IDS_2076 2076 // "Surface-based images (*.8.." -#define IDS_2077 2077 // "Click to capture mouse" -#define IDS_2078 2078 // "Press F12-F8 to release mouse" -#define IDS_2079 2079 // "Press F12-F8 or middle button.." -#define IDS_2080 2080 // "Unable to initialize Flui.." -#define IDS_2081 2081 // "Bus" -#define IDS_2082 2082 // "File" -#define IDS_2083 2083 // "C" -#define IDS_2084 2084 // "H" -#define IDS_2085 2085 // "S" -#define IDS_2086 2086 // "MB" -#define IDS_2087 2087 // "Check BPB" -#define IDS_2088 2088 // "KB" -#define IDS_2089 2089 // "Could not initialize the video..." -#define IDS_2090 2090 // "Default" -#define IDS_2091 2091 // "%i Wait state(s)" -#define IDS_2092 2092 // "Type" -#define IDS_2093 2093 // "PCap failed to set up.." -#define IDS_2094 2094 // "No PCap devices found" -#define IDS_2095 2095 // "Invalid PCap device" -#define IDS_2096 2096 // "Standard 2-button joystick(s)" -#define IDS_2097 2097 // "Standard 4-button joystick" -#define IDS_2098 2098 // "Standard 6-button joystick" -#define IDS_2099 2099 // "Standard 8-button joystick" -#define IDS_2100 2100 // "CH Flightstick Pro" -#define IDS_2101 2101 // "Microsoft SideWinder Pad" -#define IDS_2102 2102 // "Thrustmaster Flight Cont.." -#define IDS_2103 2103 // "None" -#define IDS_2104 2104 // "Unable to load keyboard..." -#define IDS_2105 2105 // "Unable to register raw input." -#define IDS_2106 2106 // "%u" -#define IDS_2107 2107 // "%u MB (CHS: %i, %i, %i)" -#define IDS_2108 2108 // "Floppy %i (%s): %ls" -#define IDS_2109 2109 // "All floppy images (*.0??;*.." -#define IDS_2110 2110 // "Unable to initialize Free.." -#define IDS_2111 2111 // "Unable to initialize SDL..." -#define IDS_2112 2112 // "Are you sure you want to..." +#define IDS_STRINGS 2048 // "86Box" +#define IDS_2049 2049 // "Error" +#define IDS_2050 2050 // "Fatal error" +#define IDS_2051 2051 // " - PAUSED" +#define IDS_2052 2052 // "Press Ctrl+Alt+PgDn..." +#define IDS_2053 2053 // "Speed" +#define IDS_2054 2054 // "ZIP %i (%03i): %ls" +#define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..." +#define IDS_2056 2056 // "No usable ROM images found!" +#define IDS_2057 2057 // "(empty)" +#define IDS_2058 2058 // "ZIP images (*.IM?)\0*.IM..." +#define IDS_2059 2059 // "(Turbo)" +#define IDS_2060 2060 // "On" +#define IDS_2061 2061 // "Off" +#define IDS_2062 2062 // "All floppy images (*.DSK..." +#define IDS_2063 2063 // "Machine ""%hs"" is not..." +#define IDS_2064 2064 // "Video card ""%hs"" is not..." +#define IDS_2065 2065 // "Machine" +#define IDS_2066 2066 // "Display" +#define IDS_2067 2067 // "Input devices" +#define IDS_2068 2068 // "Sound" +#define IDS_2069 2069 // "Network" +#define IDS_2070 2070 // "Ports (COM & LPT)" +#define IDS_2071 2071 // "Storage controllers" +#define IDS_2072 2072 // "Hard disks" +#define IDS_2073 2073 // "Floppy and CD-ROM drives" +#define IDS_2074 2074 // "Other removable devices" +#define IDS_2075 2075 // "Other peripherals" +#define IDS_2076 2076 // "Surface-based images (*.8.." +#define IDS_2077 2077 // "Click to capture mouse" +#define IDS_2078 2078 // "Press F12-F8 to release mouse" +#define IDS_2079 2079 // "Press F12-F8 or middle button.." +#define IDS_2080 2080 // "Unable to initialize Flui.." +#define IDS_2081 2081 // "Bus" +#define IDS_BUS IDS_2081 // "Bus" +#define IDS_2082 2082 // "File" +#define IDS_2083 2083 // "C" +#define IDS_2084 2084 // "H" +#define IDS_2085 2085 // "S" +#define IDS_2086 2086 // "MB" +#define IDS_MB IDS_2086 // "MB" +#define IDS_2087 2087 // "Speed" + +#define IDS_2088 2088 // "Check BPB" +#define IDS_BPB IDS_2088 // "Check BPB" + +#define IDS_2089 2089 // "KB" +#define IDS_KB IDS_2089 // "KB" + +#define IDS_2090 2090 // "Could not initialize the video..." + +#define IDS_2091 2091 // "Default" +#define IDS_DEFAULT IDS_2091 // "Default" + +#define IDS_2092 2092 // "%i Wait state(s)" +#define IDS_WS IDS_2092 // "%i Wait state(s)" + +#define IDS_2093 2093 // "Type" +#define IDS_TYPE IDS_2093 // "Type" + +/* TODO */ +#define IDS_2094 2094 // "PCap failed to set up.." +#define IDS_2095 2095 // "No PCap devices found" +#define IDS_2096 2096 // "Invalid PCap device" +#define IDS_2097 2097 // "Standard 2-button joystick(s)" +#define IDS_2098 2098 // "Standard 4-button joystick" +#define IDS_2099 2099 // "Standard 6-button joystick" +#define IDS_2100 2100 // "Standard 8-button joystick" +#define IDS_2101 2101 // "CH Flightstick Pro" +#define IDS_2102 2102 // "Microsoft SideWinder Pad" +#define IDS_2103 2103 // "Thrustmaster Flight Cont.." +#define IDS_2104 2104 // "None" +#define IDS_2105 2105 // "Unable to load keyboard..." +#define IDS_2106 2106 // "Unable to register raw input." +#define IDS_2107 2107 // "%u" +#define IDS_2108 2108 // "%u MB (CHS: %i, %i, %i)" +#define IDS_2109 2109 // "Floppy %i (%s): %ls" +#define IDS_2110 2110 // "All floppy images (*.0??;*.." +#define IDS_2111 2111 // "Unable to initialize Free.." +#define IDS_2112 2112 // "Unable to initialize SDL..." #define IDS_2113 2113 // "Are you sure you want to..." -#define IDS_2114 2114 // "Unable to initialize Ghostscript..." -#define IDS_2115 2115 // "MO %i (%03i): %ls" -#define IDS_2116 2116 // "MO images (*.IM?)\0*.IM..." -#define IDS_2117 2117 // "Welcome to 86Box!" -#define IDS_2118 2118 // "Internal controller" -#define IDS_2119 2119 // "Exit" -#define IDS_2120 2120 // "No ROMs found" -#define IDS_2121 2121 // "Do you want to save the settings?" -#define IDS_2122 2122 // "This will hard reset the emulated..." -#define IDS_2123 2123 // "Save" -#define IDS_2124 2124 // "About 86Box" -#define IDS_2125 2125 // "86Box v" EMU_VERSION -#define IDS_2126 2126 // "An emulator of old computers..." -#define IDS_2127 2127 // "OK" -#define IDS_2128 2128 // "Hardware not available" -#define IDS_2129 2129 // "Make sure " LIB_NAME_PCAP "..." -#define IDS_2130 2130 // "Invalid configuration" -#define IDS_2131 2131 // LIB_NAME_FREETYPE " is required..." -#define IDS_2132 2132 // LIB_NAME_GS " is required for... -#define IDS_2133 2133 // LIB_NAME_FLUIDSYNTH " is required..." -#define IDS_2134 2134 // "Entering fullscreen mode" -#define IDS_2135 2135 // "Don't show this message again" -#define IDS_2136 2136 // "Don't exit" -#define IDS_2137 2137 // "Reset" -#define IDS_2138 2138 // "Don't reset" -#define IDS_2139 2139 // "MO images (*.IM?)\0*.IM?..." -#define IDS_2140 2140 // "CD-ROM images (*.ISO;*.CU.." -#define IDS_2141 2141 // "%hs Device Configuration" -#define IDS_2142 2142 // "Monitor in sleep mode" -#define IDS_2143 2143 // "OpenGL Shaders (*.GLSL)..." -#define IDS_2144 2144 // "OpenGL options" -#define IDS_2145 2145 // "You are loading an unsupported..." -#define IDS_2146 2146 // "CPU type filtering based on..." -#define IDS_2147 2147 // "Continue" -#define IDS_2148 2148 // "Cassette: %s" -#define IDS_2149 2149 // "Cassette images (*.PCM;*.RAW;*..." -#define IDS_2150 2150 // "Cartridge %i: %ls" -#define IDS_2151 2151 // "Cartridge images (*.JRC)\0*.JRC\0..." -#define IDS_2152 2152 // "Error initializing renderer" -#define IDS_2153 2153 // "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -#define IDS_2154 2154 // "Resume execution" -#define IDS_2155 2155 // "Pause execution" -#define IDS_2156 2156 // "Press Ctrl+Alt+Del" -#define IDS_2157 2157 // "Press Ctrl+Alt+Esc" -#define IDS_2158 2158 // "Hard reset" -#define IDS_2159 2159 // "ACPI shutdown" -#define IDS_2160 2160 // "Settings" -#define IDS_2161 2161 // "Early drive" +#define IDS_2114 2114 // "Are you sure you want to..." +#define IDS_2115 2115 // "Unable to initialize Ghostscript..." +#define IDS_2116 2116 // "MO %i (%03i): %ls" +#define IDS_2117 2117 // "MO images (*.IM?)\0*.IM..." +#define IDS_2118 2118 // "Welcome to 86Box!" +#define IDS_2119 2119 // "Internal controller" +#define IDS_2120 2120 // "Exit" +#define IDS_2121 2121 // "No ROMs found" +#define IDS_2122 2122 // "Do you want to save the settings?" +#define IDS_2123 2123 // "This will hard reset the emulated..." +#define IDS_2124 2124 // "Save" +#define IDS_2125 2125 // "About 86Box" +#define IDS_2126 2126 // "86Box v" EMU_VERSION +#define IDS_2127 2127 // "An emulator of old computers..." +#define IDS_2128 2128 // "OK" +#define IDS_2129 2129 // "Hardware not available" +#define IDS_2130 2130 // "Make sure " LIB_NAME_PCAP "..." +#define IDS_2131 2131 // "Invalid configuration" +#define IDS_2132 2132 // LIB_NAME_FREETYPE " is required..." +#define IDS_2133 2133 // LIB_NAME_GS " is required for... +#define IDS_2134 2134 // LIB_NAME_FLUIDSYNTH " is required..." +#define IDS_2135 2135 // "Entering fullscreen mode" +#define IDS_2136 2136 // "Don't show this message again" +#define IDS_2137 2137 // "Don't exit" +#define IDS_2138 2138 // "Reset" +#define IDS_2139 2139 // "Don't reset" +#define IDS_2140 2140 // "MO images (*.IM?)\0*.IM?..." +#define IDS_2141 2141 // "CD-ROM images (*.ISO;*.CU.." +#define IDS_2142 2142 // "%hs Device Configuration" +#define IDS_2143 2143 // "Monitor in sleep mode" +#define IDS_2144 2144 // "OpenGL Shaders (*.GLSL)..." +#define IDS_2145 2145 // "OpenGL options" +#define IDS_2146 2146 // "You are loading an unsupported..." +#define IDS_2147 2147 // "CPU type filtering based on..." +#define IDS_2148 2148 // "Continue" +#define IDS_2149 2149 // "Cassette: %s" +#define IDS_2150 2150 // "Cassette images (*.PCM;*.RAW;*..." +#define IDS_2151 2151 // "Cartridge %i: %ls" +#define IDS_2152 2152 // "Cartridge images (*.JRC)\0*.JRC\0..." +#define IDS_2153 2153 // "Error initializing renderer" +#define IDS_2154 2154 // "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +#define IDS_2155 2155 // "Resume execution" +#define IDS_2156 2156 // "Pause execution" +#define IDS_2157 2157 // "Press Ctrl+Alt+Del" +#define IDS_2158 2158 // "Press Ctrl+Alt+Esc" +#define IDS_2159 2159 // "Hard reset" +#define IDS_2160 2160 // "ACPI shutdown" +#define IDS_2161 2161 // "Settings" +#define IDS_2162 2162 // "Early drive" #define IDS_4096 4096 // "Hard disk (%s)" #define IDS_4097 4097 // "%01i:%01i" @@ -243,16 +260,16 @@ #define IDS_LANG_ENUS IDS_7168 -#define STR_NUM_2048 114 +#define STR_NUM_2048 115 // UNUSED: #define STR_NUM_3072 11 -#define STR_NUM_4096 40 -#define STR_NUM_4352 6 -#define STR_NUM_4608 6 -#define STR_NUM_5120 1 -#define STR_NUM_5376 7 -#define STR_NUM_5632 7 -#define STR_NUM_5888 24 -#define STR_NUM_6144 4 -#define STR_NUM_7168 1 +#define STR_NUM_4096 40 +#define STR_NUM_4352 6 +#define STR_NUM_4608 6 +#define STR_NUM_5120 1 +#define STR_NUM_5376 7 +#define STR_NUM_5632 7 +#define STR_NUM_5888 24 +#define STR_NUM_6144 4 +#define STR_NUM_7168 1 #endif /*LANG_UAGE_H*/ diff --git a/src/include/86box/m_xt_xi8088.h b/src/include/86box/m_xt_xi8088.h index 99e8826ac..d9c963047 100644 --- a/src/include/86box/m_xt_xi8088.h +++ b/src/include/86box/m_xt_xi8088.h @@ -5,9 +5,9 @@ extern const device_t xi8088_device; -uint8_t xi8088_turbo_get(); +uint8_t xi8088_turbo_get(void); void xi8088_turbo_set(uint8_t value); void xi8088_bios_128kb_set(int val); -int xi8088_bios_128kb(); +int xi8088_bios_128kb(void); #endif /*MACHINE_XI80888_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index aeca2e900..596972ded 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -127,7 +127,10 @@ #define IS_AT(m) (((machines[m].bus_flags & (MACHINE_BUS_ISA16 | MACHINE_BUS_EISA | MACHINE_BUS_VLB | MACHINE_BUS_MCA | MACHINE_BUS_PCI | MACHINE_BUS_PCMCIA | MACHINE_BUS_AGP | MACHINE_BUS_AC97)) && !(machines[m].bus_flags & MACHINE_PC98)) ? 1 : 0) #define CPU_BLOCK(...) \ - (const uint8_t[]) { __VA_ARGS__, 0 } + (const uint8_t[]) \ + { \ + __VA_ARGS__, 0 \ + } #define MACHINE_MULTIPLIER_FIXED -1 #define CPU_BLOCK_NONE 0 @@ -337,6 +340,7 @@ extern int machine_get_ram_granularity(int m); extern int machine_get_type(int m); extern void machine_close(void); extern int machine_has_mouse(void); +extern int machine_is_sony(void); extern uint8_t machine_get_p1(void); extern void machine_load_p1(int m); diff --git a/src/include/86box/machine_status.h b/src/include/86box/machine_status.h index 9e33c293a..6948dc556 100644 --- a/src/include/86box/machine_status.h +++ b/src/include/86box/machine_status.h @@ -27,6 +27,6 @@ typedef struct { extern machine_status_t machine_status; -extern void machine_status_init(); +extern void machine_status_init(void); #endif /*EMU_MACHINE_STATUS_H*/ \ No newline at end of file diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index d3ed78af4..e2b8c2626 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -25,13 +25,13 @@ extern char *midi_out_device_get_internal_name(int card); extern char *midi_in_device_get_internal_name(int card); extern int midi_out_device_get_from_internal_name(char *s); extern int midi_in_device_get_from_internal_name(char *s); -extern void midi_out_device_init(); -extern void midi_in_device_init(); +extern void midi_out_device_init(void); +extern void midi_in_device_init(void); typedef struct midi_device_t { void (*play_sysex)(uint8_t *sysex, unsigned int len); void (*play_msg)(uint8_t *msg); - void (*poll)(); + void (*poll)(void); int (*write)(uint8_t val); } midi_device_t; @@ -60,13 +60,13 @@ extern midi_t *midi_out, *midi_in; extern void midi_out_init(midi_device_t *device); extern void midi_in_init(midi_device_t *device, midi_t **mididev); -extern void midi_out_close(); +extern void midi_out_close(void); extern void midi_in_close(void); extern void midi_raw_out_rt_byte(uint8_t val); extern void midi_raw_out_thru_rt_byte(uint8_t val); extern void midi_raw_out_byte(uint8_t val); extern void midi_clear_buffer(void); -extern void midi_poll(); +extern void midi_poll(void); extern void midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p); extern void midi_in_handlers_clear(void); diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index e1ec25c8a..ea22f8f29 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -168,7 +168,7 @@ extern void mo_hard_reset(void); extern void mo_reset(scsi_common_t *sc); extern int mo_load(mo_t *dev, char *fn); -extern void mo_close(); +extern void mo_close(void); #ifdef __cplusplus } diff --git a/src/include/86box/net_3c501.h b/src/include/86box/net_3c501.h new file mode 100644 index 000000000..e45f9a82a --- /dev/null +++ b/src/include/86box/net_3c501.h @@ -0,0 +1,44 @@ +/* + * 86Box An emulator of (mostly) x86-based PC systems and devices, + * using the ISA, EISA, VLB, MCA, and PCI system buses, + * roughly spanning the era between 1981 and 1995. + * + * This file is part of the 86Box Project. + * + * Implementation of the following network controller: + * - 3Com Etherlink 3c500/3c501 (ISA 8-bit). + * + * + * + * Based on @(#)Dev3C501.cpp Oracle (VirtualBox) + * + * Authors: TheCollector1995, + * Oracle + * + * Copyright 2022 TheCollector1995. + * Portions Copyright (C) 2022 Oracle and/or its affilitates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#ifndef NET_3C501_H +#define NET_3C501_H + +extern const device_t threec501_device; + +#endif /*NET_3C501_H*/ diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 292c863fa..0a396968f 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -89,14 +89,14 @@ enum { }; typedef struct { - int device_num; + uint16_t device_num; int net_type; char host_dev_name[128]; uint32_t link_state; } netcard_conf_t; extern netcard_conf_t net_cards_conf[NET_CARD_MAX]; -extern int net_card_current; +extern uint16_t net_card_current; typedef int (*NETRXCB)(void *, uint8_t *, int); typedef int (*NETSETLINKSTATE)(void *, uint32_t link_state); @@ -135,7 +135,7 @@ struct _netcard_t { mutex_t *tx_mutex; mutex_t *rx_mutex; pc_timer_t timer; - int card_num; + uint16_t card_num; double byte_period; uint32_t led_timer; uint32_t led_state; diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 8b59c0883..47e52c95b 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -111,7 +111,7 @@ extern int nvr_save(void); extern int nvr_is_leap(int year); extern int nvr_get_days(int month, int year); -extern void nvr_time_sync(); +extern void nvr_time_sync(void); extern void nvr_time_get(struct tm *); extern void nvr_time_set(struct tm *); diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 9f45aa0a0..5c24bebf2 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -22,38 +22,38 @@ #ifndef EMU_PCI_H #define EMU_PCI_H -#define PCI_REG_COMMAND 0x04 +#define PCI_REG_COMMAND 0x04 -#define PCI_COMMAND_IO 0x01 -#define PCI_COMMAND_MEM 0x02 +#define PCI_COMMAND_IO 0x01 +#define PCI_COMMAND_MEM 0x02 -#define PCI_NO_IRQ_STEERING 0x8000 -#define PCI_CAN_SWITCH_TYPE 0x10000 -#define PCI_NO_BRIDGES 0x20000 -#define PCI_ALWAYS_EXPOSE_DEV0 0x40000 +#define PCI_NO_IRQ_STEERING 0x8000 +#define PCI_CAN_SWITCH_TYPE 0x10000 +#define PCI_NO_BRIDGES 0x20000 +#define PCI_ALWAYS_EXPOSE_DEV0 0x40000 -#define PCI_CONFIG_TYPE_1 1 -#define PCI_CONFIG_TYPE_2 2 +#define PCI_CONFIG_TYPE_1 1 +#define PCI_CONFIG_TYPE_2 2 -#define PCI_CONFIG_TYPE_MASK 0x7fff +#define PCI_CONFIG_TYPE_MASK 0x7fff -#define PCI_INTA 1 -#define PCI_INTB 2 -#define PCI_INTC 3 -#define PCI_INTD 4 +#define PCI_INTA 1 +#define PCI_INTB 2 +#define PCI_INTC 3 +#define PCI_INTD 4 -#define PCI_MIRQ0 0 -#define PCI_MIRQ1 1 -#define PCI_MIRQ2 2 -#define PCI_MIRQ3 3 -#define PCI_MIRQ4 4 -#define PCI_MIRQ5 5 -#define PCI_MIRQ6 6 -#define PCI_MIRQ7 7 +#define PCI_MIRQ0 0 +#define PCI_MIRQ1 1 +#define PCI_MIRQ2 2 +#define PCI_MIRQ3 3 +#define PCI_MIRQ4 4 +#define PCI_MIRQ5 5 +#define PCI_MIRQ6 6 +#define PCI_MIRQ7 7 -#define PCI_IRQ_DISABLED -1 +#define PCI_IRQ_DISABLED -1 -#define PCI_ADD_STRICT 0x80 +#define PCI_ADD_STRICT 0x80 enum { PCI_CARD_NORTHBRIDGE = 0, @@ -113,7 +113,7 @@ extern uint8_t pci_get_int(uint8_t card, uint8_t pci_int); extern void pci_reset(void); extern void pci_init(int type); -extern uint8_t pci_register_bus(); +extern uint8_t pci_register_bus(void); extern void pci_set_pmc(uint8_t pmc); extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number); extern void pci_relocate_slot(int type, int new_slot); diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index cd88f3653..05b982216 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Define the various platform support functions. + * Define the various platform support functions. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2021 Laci bá' + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2021 Laci bá' */ #ifndef EMU_PLAT_H @@ -49,7 +49,7 @@ extern int strnicmp(const char *s1, const char *s2, size_t n); # define ftello64 ftello # define off64_t off_t #elif defined(_MSC_VER) -//# define fopen64 fopen +// # define fopen64 fopen # define fseeko64 _fseeki64 # define ftello64 _ftelli64 # define off64_t off_t @@ -107,7 +107,7 @@ extern int plat_chdir(char *path); extern void plat_tempfile(char *bufp, char *prefix, char *suffix); extern void plat_get_exe_name(char *s, int size); extern void plat_get_global_config_dir(char* strptr); -extern void plat_init_rom_paths(); +extern void plat_init_rom_paths(void); extern int plat_dir_check(char *path); extern int plat_dir_create(char *path); extern void *plat_mmap(size_t size, uint8_t executable); diff --git a/src/include/86box/plat_dir.h b/src/include/86box/plat_dir.h index 7a7876ebb..74caac23f 100644 --- a/src/include/86box/plat_dir.h +++ b/src/include/86box/plat_dir.h @@ -19,24 +19,24 @@ /* Windows needs the POSIX re-implementations */ #if defined(_WIN32) -#ifdef _MAX_FNAME -# define MAXNAMLEN _MAX_FNAME -#else -# define MAXNAMLEN 15 -#endif -#define MAXDIRLEN 127 +# ifdef _MAX_FNAME +# define MAXNAMLEN _MAX_FNAME +# else +# define MAXNAMLEN 15 +# endif +# define MAXDIRLEN 127 struct dirent { long d_ino; unsigned short d_reclen; unsigned short d_off; -#ifdef UNICODE +# ifdef UNICODE wchar_t d_name[MAXNAMLEN + 1]; -#else +# else char d_name[MAXNAMLEN + 1]; -#endif +# endif }; -#define d_namlen d_reclen +# define d_namlen d_reclen typedef struct { short flags; /* internal flags */ @@ -44,18 +44,18 @@ typedef struct { long handle; /* open handle to Win32 system */ short sts; /* last known status code */ char *dta; /* internal work data */ -#ifdef UNICODE +# ifdef UNICODE wchar_t dir[MAXDIRLEN + 1]; /* open dir */ -#else +# else char dir[MAXDIRLEN + 1]; /* open dir */ -#endif +# endif struct dirent dent; /* actual directory entry */ } DIR; /* Directory routine flags. */ -#define DIR_F_LOWER 0x0001 /* force to lowercase */ -#define DIR_F_SANE 0x0002 /* force this to sane path */ -#define DIR_F_ISROOT 0x0010 /* this is the root directory */ +# define DIR_F_LOWER 0x0001 /* force to lowercase */ +# define DIR_F_SANE 0x0002 /* force this to sane path */ +# define DIR_F_ISROOT 0x0010 /* this is the root directory */ /* Function prototypes. */ extern DIR *opendir(const char *); @@ -64,11 +64,10 @@ extern long telldir(DIR *); extern void seekdir(DIR *, long); extern int closedir(DIR *); -#define rewinddir(dirp) seekdir(dirp, 0L) +# define rewinddir(dirp) seekdir(dirp, 0L) #else /* On linux and macOS, use the standard functions and types */ -#include +# include #endif - #endif /*PLAT_DIR_H*/ diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index c45f7cf60..dc54b504f 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -71,87 +71,90 @@ #define IDT_MEMORY 1714 /* Memory: */ /* DLG_CFG_VIDEO */ -#define IDT_VIDEO 1715 /* Video: */ +#define IDT_VIDEO 1715 /* Video: */ +#define IDT_VIDEO_2 1716 /* Video 2: */ /* DLG_CFG_INPUT */ -#define IDT_MOUSE 1716 /* Mouse: */ -#define IDT_JOYSTICK 1717 /* Joystick: */ +#define IDT_MOUSE 1717 /* Mouse: */ +#define IDT_JOYSTICK 1718 /* Joystick: */ /* DLG_CFG_SOUND */ -#define IDT_SOUND 1718 /* Sound card: */ -#define IDT_MIDI_OUT 1719 /* MIDI Out Device: */ -#define IDT_MIDI_IN 1720 /* MIDI In Device: */ +#define IDT_SOUND 1719 /* Sound card: */ +#define IDT_MIDI_OUT 1720 /* MIDI Out Device: */ +#define IDT_MIDI_IN 1721 /* MIDI In Device: */ /* DLG_CFG_NETWORK */ -#define IDT_NET_TYPE 1721 /* Network type: */ -#define IDT_PCAP 1722 /* PCap device: */ -#define IDT_NET 1723 /* Network adapter: */ +#define IDT_NET_TYPE 1722 /* Network type: */ +#define IDT_PCAP 1723 /* PCap device: */ +#define IDT_NET 1724 /* Network adapter: */ /* DLG_CFG_PORTS */ -#define IDT_COM1 1724 /* COM1 Device: */ -#define IDT_COM2 1725 /* COM1 Device: */ -#define IDT_COM3 1726 /* COM1 Device: */ -#define IDT_COM4 1727 /* COM1 Device: */ +#define IDT_COM1 1725 /* COM1 Device: */ +#define IDT_COM2 1726 /* COM1 Device: */ +#define IDT_COM3 1727 /* COM1 Device: */ +#define IDT_COM4 1728 /* COM1 Device: */ -#define IDT_LPT1 1728 /* LPT1 Device: */ -#define IDT_LPT2 1729 /* LPT2 Device: */ -#define IDT_LPT3 1730 /* LPT3 Device: */ -#define IDT_LPT4 1731 /* LPT4 Device: */ +#define IDT_LPT1 1729 /* LPT1 Device: */ +#define IDT_LPT2 1730 /* LPT2 Device: */ +#define IDT_LPT3 1731 /* LPT3 Device: */ +#define IDT_LPT4 1732 /* LPT4 Device: */ /* DLG_CFG_STORAGE */ -#define IDT_HDC 1732 /* HD Controller: */ -#define IDT_FDC 1733 /* Ext FD Controller: */ -#define IDT_SCSI_1 1734 /* SCSI Board #1: */ -#define IDT_SCSI_2 1735 /* SCSI Board #2: */ -#define IDT_SCSI_3 1736 /* SCSI Board #3: */ -#define IDT_SCSI_4 1737 /* SCSI Board #4: */ +#define IDT_HDC 1733 /* HD Controller: */ +#define IDT_FDC 1734 /* Ext FD Controller: */ +#define IDT_SCSI_1 1735 /* SCSI Board #1: */ +#define IDT_SCSI_2 1736 /* SCSI Board #2: */ +#define IDT_SCSI_3 1737 /* SCSI Board #3: */ +#define IDT_SCSI_4 1738 /* SCSI Board #4: */ /* DLG_CFG_HARD_DISKS */ -#define IDT_HDD 1738 /* Hard disks: */ -#define IDT_BUS 1739 /* Bus: */ -#define IDT_CHANNEL 1740 /* Channel: */ -#define IDT_ID 1741 /* ID: */ -#define IDT_LUN 1742 /* LUN: */ +#define IDT_HDD 1739 /* Hard disks: */ +#define IDT_BUS 1740 /* Bus: */ +#define IDT_CHANNEL 1741 /* Channel: */ +#define IDT_ID 1742 /* ID: */ +#define IDT_LUN 1743 /* LUN: */ +#define IDT_SPEED 1744 /* Speed: */ /* DLG_CFG_HARD_DISKS_ADD */ -#define IDT_SECTORS 1743 /* Sectors: */ -#define IDT_HEADS 1744 /* Heads: */ -#define IDT_CYLS 1745 /* Cylinders: */ -#define IDT_SIZE_MB 1746 /* Size (MB): */ -#define IDT_TYPE 1747 /* Type: */ -#define IDT_FILE_NAME 1748 /* File name: */ -#define IDT_IMG_FORMAT 1749 /* Image Format: */ -#define IDT_BLOCK_SIZE 1750 /* Block Size: */ -#define IDT_PROGRESS 1751 /* Progress: */ +#define IDT_SECTORS 1745 /* Sectors: */ +#define IDT_HEADS 1746 /* Heads: */ +#define IDT_CYLS 1747 /* Cylinders: */ +#define IDT_SIZE_MB 1748 /* Size (MB): */ +#define IDT_TYPE 1749 /* Type: */ +#define IDT_FILE_NAME 1750 /* File name: */ +#define IDT_IMG_FORMAT 1751 /* Image Format: */ +#define IDT_BLOCK_SIZE 1752 /* Block Size: */ +#define IDT_PROGRESS 1753 /* Progress: */ /* DLG_CFG_FLOPPY_AND_CDROM_DRIVES */ -#define IDT_FLOPPY_DRIVES 1752 /* Floppy drives: */ -#define IDT_FDD_TYPE 1753 /* Type: */ -#define IDT_CD_DRIVES 1754 /* CD-ROM drives: */ -#define IDT_CD_BUS 1755 /* Bus: */ -#define IDT_CD_ID 1756 /* ID: */ -#define IDT_CD_CHANNEL 1757 /* Channel: */ -#define IDT_CD_SPEED 1758 /* Speed: */ +#define IDT_FLOPPY_DRIVES 1754 /* Floppy drives: */ +#define IDT_FDD_TYPE 1755 /* Type: */ +#define IDT_CD_DRIVES 1756 /* CD-ROM drives: */ +#define IDT_CD_BUS 1757 /* Bus: */ +#define IDT_CD_ID 1758 /* ID: */ +#define IDT_CD_LUN 1759 /* LUN: */ +#define IDT_CD_CHANNEL 1760 /* Channel: */ +#define IDT_CD_SPEED 1761 /* Speed: */ /* DLG_CFG_OTHER_REMOVABLE_DEVICES */ -#define IDT_MO_DRIVES 1760 /* MO drives: */ -#define IDT_MO_BUS 1761 /* Bus: */ -#define IDT_MO_ID 1762 /* ID: */ -#define IDT_MO_CHANNEL 1763 /* Channel */ -#define IDT_MO_TYPE 1764 /* Type: */ +#define IDT_MO_DRIVES 1762 /* MO drives: */ +#define IDT_MO_BUS 1763 /* Bus: */ +#define IDT_MO_ID 1764 /* ID: */ +#define IDT_MO_CHANNEL 1765 /* Channel */ +#define IDT_MO_TYPE 1766 /* Type: */ -#define IDT_ZIP_DRIVES 1765 /* ZIP drives: */ -#define IDT_ZIP_BUS 1766 /* Bus: */ -#define IDT_ZIP_ID 1767 /* ID: */ -#define IDT_ZIP_LUN 1768 /* LUN: */ -#define IDT_ZIP_CHANNEL 1769 /* Channel: */ +#define IDT_ZIP_DRIVES 1767 /* ZIP drives: */ +#define IDT_ZIP_BUS 1768 /* Bus: */ +#define IDT_ZIP_ID 1769 /* ID: */ +#define IDT_ZIP_LUN 1770 /* LUN: */ +#define IDT_ZIP_CHANNEL 1771 /* Channel: */ /* DLG_CFG_PERIPHERALS */ -#define IDT_ISARTC 1770 /* ISA RTC: */ -#define IDT_ISAMEM_1 1771 /* ISAMEM Board #1: */ -#define IDT_ISAMEM_2 1772 /* ISAMEM Board #2: */ -#define IDT_ISAMEM_3 1773 /* ISAMEM Board #3: */ -#define IDT_ISAMEM_4 1774 /* ISAMEM Board #4: */ +#define IDT_ISARTC 1772 /* ISA RTC: */ +#define IDT_ISAMEM_1 1773 /* ISAMEM Board #1: */ +#define IDT_ISAMEM_2 1774 /* ISAMEM Board #2: */ +#define IDT_ISAMEM_3 1775 /* ISAMEM Board #3: */ +#define IDT_ISAMEM_4 1776 /* ISAMEM Board #4: */ /* * To try to keep these organized, we now group the @@ -181,11 +184,13 @@ #define IDC_VIDEO 1020 /* video config */ #define IDC_COMBO_VIDEO 1021 -#define IDC_CHECK_VOODOO 1022 -#define IDC_BUTTON_VOODOO 1023 -#define IDC_CHECK_IBM8514 1024 -#define IDC_CHECK_XGA 1025 -#define IDC_BUTTON_XGA 1026 +#define IDC_VIDEO_2 1022 +#define IDC_COMBO_VIDEO_2 1023 +#define IDC_CHECK_VOODOO 1024 +#define IDC_BUTTON_VOODOO 1025 +#define IDC_CHECK_IBM8514 1026 +#define IDC_CHECK_XGA 1027 +#define IDC_BUTTON_XGA 1028 #define IDC_INPUT 1030 /* input config */ #define IDC_COMBO_MOUSE 1031 @@ -323,19 +328,20 @@ /* For the DeviceConfig code, re-do later. */ #define IDC_CONFIG_BASE 1300 #define IDC_CONFIGURE_VID 1300 -#define IDC_CONFIGURE_SND 1301 -#define IDC_CONFIGURE_VOODOO 1302 -#define IDC_CONFIGURE_MOD 1303 -#define IDC_CONFIGURE_NET_TYPE 1304 -#define IDC_CONFIGURE_BUSLOGIC 1305 -#define IDC_CONFIGURE_PCAP 1306 -#define IDC_CONFIGURE_NET 1307 -#define IDC_CONFIGURE_MIDI_OUT 1308 -#define IDC_CONFIGURE_MIDI_IN 1309 -#define IDC_JOY1 1310 -#define IDC_JOY2 1311 -#define IDC_JOY3 1312 -#define IDC_JOY4 1313 +#define IDC_CONFIGURE_VID_2 1301 +#define IDC_CONFIGURE_SND 1302 +#define IDC_CONFIGURE_VOODOO 1303 +#define IDC_CONFIGURE_MOD 1304 +#define IDC_CONFIGURE_NET_TYPE 1305 +#define IDC_CONFIGURE_BUSLOGIC 1306 +#define IDC_CONFIGURE_PCAP 1307 +#define IDC_CONFIGURE_NET 1308 +#define IDC_CONFIGURE_MIDI_OUT 1309 +#define IDC_CONFIGURE_MIDI_IN 1310 +#define IDC_JOY1 1311 +#define IDC_JOY2 1312 +#define IDC_JOY3 1313 +#define IDC_JOY4 1314 #define IDC_HDTYPE 1380 #define IDC_RENDER 1381 #define IDC_STATUS 1382 @@ -366,8 +372,9 @@ #define IDM_VID_HIDE_TOOLBAR 40023 #define IDM_UPDATE_ICONS 40030 #define IDM_SND_GAIN 40031 -#define IDM_VID_RESIZE 40040 -#define IDM_VID_REMEMBER 40041 +#define IDM_VID_MONITORS 40040 +#define IDM_VID_RESIZE 40041 +#define IDM_VID_REMEMBER 40042 #define IDM_VID_SDL_SW 40050 #define IDM_VID_SDL_HW 40051 #define IDM_VID_SDL_OPENGL 40052 diff --git a/src/include/86box/rom.h b/src/include/86box/rom.h index 8cc85934d..82a1aef5f 100644 --- a/src/include/86box/rom.h +++ b/src/include/86box/rom.h @@ -51,38 +51,38 @@ extern uint8_t rom_read(uint32_t addr, void *p); extern uint16_t rom_readw(uint32_t addr, void *p); extern uint32_t rom_readl(uint32_t addr, void *p); -extern FILE *rom_fopen(char *fn, char *mode); +extern FILE *rom_fopen(const char *fn, char *mode); extern int rom_getfile(char *fn, char *s, int size); extern int rom_present(char *fn); -extern int rom_load_linear_oddeven(char *fn, uint32_t addr, int sz, +extern int rom_load_linear_oddeven(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr); -extern int rom_load_linear(char *fn, uint32_t addr, int sz, +extern int rom_load_linear(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr); -extern int rom_load_interleaved(char *fnl, char *fnh, uint32_t addr, +extern int rom_load_interleaved(const char *fnl, const char *fnh, uint32_t addr, int sz, int off, uint8_t *ptr); extern uint8_t bios_read(uint32_t addr, void *priv); extern uint16_t bios_readw(uint32_t addr, void *priv); extern uint32_t bios_readl(uint32_t addr, void *priv); -extern int bios_load(char *fn1, char *fn2, uint32_t addr, int sz, +extern int bios_load(const char *fn1, const char *fn2, uint32_t addr, int sz, int off, int flags); -extern int bios_load_linear_combined(char *fn1, char *fn2, +extern int bios_load_linear_combined(const char *fn1, const char *fn2, int sz, int off); -extern int bios_load_linear_combined2(char *fn1, char *fn2, - char *fn3, char *fn4, char *fn5, +extern int bios_load_linear_combined2(const char *fn1, const char *fn2, + const char *fn3, const char *fn4, const char *fn5, int sz, int off); -extern int bios_load_linear_combined2_ex(char *fn1, char *fn2, - char *fn3, char *fn4, char *fn5, +extern int bios_load_linear_combined2_ex(const char *fn1, const char *fn2, + const char *fn3, const char *fn4, const char *fn5, int sz, int off); -extern int rom_init(rom_t *rom, char *fn, uint32_t address, int size, +extern int rom_init(rom_t *rom, const char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); -extern int rom_init_oddeven(rom_t *rom, char *fn, uint32_t address, int size, +extern int rom_init_oddeven(rom_t *rom, const char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); -extern int rom_init_interleaved(rom_t *rom, char *fn_low, - char *fn_high, uint32_t address, +extern int rom_init_interleaved(rom_t *rom, const char *fn_low, + const char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags); diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 87b91a30a..1394a1c53 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Definitions for the NS8250/16450/16550/16650/16750/16850/16950 - * UART emulation. + * Definitions for the NS8250/16450/16550/16650/16750/16850/16950 + * UART emulation. * * * - * Author: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #ifndef EMU_SERIAL_H diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index f9f73a60c..bdf5022e5 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -66,6 +66,7 @@ extern void ad1848_write(uint16_t addr, uint8_t val, void *priv); extern void ad1848_update(ad1848_t *ad1848); extern void ad1848_speed_changed(ad1848_t *ad1848); extern void ad1848_filter_cd_audio(int channel, double *buffer, void *priv); +extern void ad1848_filter_aux2(void* priv, double* out_l, double* out_r); extern void ad1848_init(ad1848_t *ad1848, uint8_t type); diff --git a/src/include/86box/snd_opl.h b/src/include/86box/snd_opl.h index 38a411ada..5caccf8fc 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -21,6 +21,7 @@ enum fm_type { FM_YM3812 = 0, FM_YMF262, FM_YMF289B, + FM_YMF278B, FM_MAX }; @@ -51,6 +52,7 @@ extern const device_t ymf262_nuked_device; extern const device_t ym3812_ymfm_device; extern const device_t ymf262_ymfm_device; extern const device_t ymf289b_ymfm_device; +extern const device_t ymf278b_ymfm_device; #endif #endif /*SOUND_OPL_H*/ diff --git a/src/include/86box/snd_resid.h b/src/include/86box/snd_resid.h index b8763ad15..710ff4a61 100644 --- a/src/include/86box/snd_resid.h +++ b/src/include/86box/snd_resid.h @@ -4,7 +4,7 @@ #ifdef __cplusplus extern "C" { #endif -void *sid_init(); +void *sid_init(void); void sid_close(void *p); void sid_reset(void *p); uint8_t sid_read(uint16_t addr, void *p); diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index 782a947f6..577335976 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -147,6 +147,9 @@ typedef struct sb_t { pnp_rom[512]; uint16_t opl_pnp_addr; + + void *opl_mixer; + void (*opl_mix)(void*, double*, double*); } sb_t; extern void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p); diff --git a/src/include/86box/snd_speaker.h b/src/include/86box/snd_speaker.h index 0b368268e..922603d98 100644 --- a/src/include/86box/snd_speaker.h +++ b/src/include/86box/snd_speaker.h @@ -25,7 +25,7 @@ extern int speaker_mute; extern int speaker_gated; extern int speaker_enable, was_speaker_enable; -extern void speaker_init(); +extern void speaker_init(void); extern void speaker_set_count(uint8_t new_m, int new_count); extern void speaker_update(void); diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 22606b481..10303c3ca 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -81,6 +81,7 @@ extern const device_t adgold_device; /* Aztech Sound Galaxy 16 */ extern const device_t azt2316a_device; extern const device_t acermagic_s20_device; +extern const device_t mirosound_pcm10_device; extern const device_t azt1605_device; /* Ensoniq AudioPCI */ diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index a8cef77fe..4421840d6 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -68,8 +68,8 @@ void cga_poll(void *p); #ifdef EMU_DEVICE_H extern const device_config_t cga_config[]; -extern const device_t cga_device; -extern const device_t cga_pravetz_device; +extern const device_t cga_device; +extern const device_t cga_pravetz_device; #endif #endif /*VIDEO_CGA_H*/ diff --git a/src/include/86box/vid_cga_comp.h b/src/include/86box/vid_cga_comp.h index bbde070c1..f4dd58b40 100644 --- a/src/include/86box/vid_cga_comp.h +++ b/src/include/86box/vid_cga_comp.h @@ -23,7 +23,7 @@ #define Bit8u uint8_t #define Bit32u uint32_t #define Bitu unsigned int -#define bool uint8_t +#define bool uint8_t void update_cga16_color(uint8_t cgamode); void cga_comp_init(int revision); diff --git a/src/include/86box/vid_nga.h b/src/include/86box/vid_nga.h index ebde4978b..8dc0ad881 100644 --- a/src/include/86box/vid_nga.h +++ b/src/include/86box/vid_nga.h @@ -42,7 +42,7 @@ void nga_write(uint32_t addr, uint8_t val, void *priv); uint8_t nga_read(uint32_t addr, void *priv); void nga_poll(void *priv); void nga_close(void *priv); -void nga_mdaattr_rebuild(); +void nga_mdaattr_rebuild(void); #ifdef EMU_DEVICE_H extern const device_config_t nga_config[]; diff --git a/src/include/86box/vid_ogc.h b/src/include/86box/vid_ogc.h index 368f43a34..6e6447694 100644 --- a/src/include/86box/vid_ogc.h +++ b/src/include/86box/vid_ogc.h @@ -42,7 +42,7 @@ void ogc_write(uint32_t addr, uint8_t val, void *priv); uint8_t ogc_read(uint32_t addr, void *priv); void ogc_poll(void *priv); void ogc_close(void *priv); -void ogc_mdaattr_rebuild(); +void ogc_mdaattr_rebuild(void); #ifdef EMU_DEVICE_H extern const device_config_t ogc_config[]; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index a417d05df..3781d5530 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Generic SVGA handling. + * Generic SVGA handling. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include <86box/thread.h> @@ -211,7 +211,7 @@ extern uint8_t svga_rotate[8][256]; void svga_out(uint16_t addr, uint8_t val, void *p); uint8_t svga_in(uint16_t addr, void *p); -svga_t *svga_get_pri(); +svga_t *svga_get_pri(void); void svga_set_override(svga_t *svga, int val); void svga_set_ramdac_type(svga_t *svga, int type); diff --git a/src/include/86box/vid_voodoo_codegen_x86.h b/src/include/86box/vid_voodoo_codegen_x86.h index 9432fa3b3..c04330190 100644 --- a/src/include/86box/vid_voodoo_codegen_x86.h +++ b/src/include/86box/vid_voodoo_codegen_x86.h @@ -2075,12 +2075,12 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x05); addlong((uint32_t) &xmm_ff_b); } - //#if 0 - // addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ - // addbyte(0x0f); - // addbyte(0x7e); - // addbyte(0x87); - // addlong(offsetof(voodoo_state_t, out)); + // #if 0 + // addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ + // addbyte(0x0f); + // addbyte(0x7e); + // addbyte(0x87); + // addlong(offsetof(voodoo_state_t, out)); if (params->fogMode & FOG_ENABLE) { if (params->fogMode & FOG_CONSTANT) { addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ @@ -2695,7 +2695,7 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x67); addbyte(0xc0); } - //#endif + // #endif // addbyte(0x8b); /*MOV EDX, x (ESP+12)*/ // addbyte(0x54); diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index ab55cc9f4..e6d4ad5e4 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -33,10 +33,10 @@ #define TEX_CACHE_MAX 64 #ifdef __cplusplus -#include +# include using atomic_int = std::atomic; #else -#include +# include #endif enum { @@ -320,7 +320,7 @@ typedef struct voodoo_t { uint32_t cmdfifo_amin, cmdfifo_amax; int cmdfifo_holecount; - atomic_uint cmd_status; + atomic_uint cmd_status; uint32_t sSetupMode; vert_t verts[4]; diff --git a/src/include/86box/vid_voodoo_dither.h b/src/include/86box/vid_voodoo_dither.h index 1b95e7e80..2d674c5b4 100644 --- a/src/include/86box/vid_voodoo_dither.h +++ b/src/include/86box/vid_voodoo_dither.h @@ -17,7 +17,7 @@ */ #ifndef VIDEO_VOODOO_DITHER_H -# define VIDEO_VOODOO_DITHER_H +#define VIDEO_VOODOO_DITHER_H static const uint8_t dither_rb[256][4][4] = { diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index f60b3359b..5bc580335 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * IBM XGA emulation. + * IBM XGA emulation. * * * - * Authors: TheCollector1995. + * Authors: TheCollector1995. * - * Copyright 2022 TheCollector1995. + * Copyright 2022 TheCollector1995. */ #ifndef VIDEO_XGA_H diff --git a/src/include/86box/vid_xga_device.h b/src/include/86box/vid_xga_device.h index f6effc350..a92c6d3c6 100644 --- a/src/include/86box/vid_xga_device.h +++ b/src/include/86box/vid_xga_device.h @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * IBM XGA emulation. + * IBM XGA emulation. * * * - * Authors: TheCollector1995. + * Authors: TheCollector1995. * - * Copyright 2022 TheCollector1995. + * Copyright 2022 TheCollector1995. */ #ifndef VIDEO_XGA_DEVICE_H diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 91ef40eab..abba64574 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -1,5 +1,5 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in + * 86Box A hypervisor and IBM PC system emulator that specializes in * running old operating systems and software designed for IBM * PC systems and compatibles from 1981 through fairly recent * system designs based on the PCI bus. @@ -520,12 +520,20 @@ extern const device_t ps1vga_mca_device; extern const device_t voodoo_device; extern const device_t voodoo_banshee_device; extern const device_t creative_voodoo_banshee_device; +extern const device_t voodoo_3_1000_device; +extern const device_t voodoo_3_1000_agp_device; extern const device_t voodoo_3_2000_device; extern const device_t voodoo_3_2000_agp_device; extern const device_t voodoo_3_2000_agp_onboard_8m_device; extern const device_t voodoo_3_3000_device; extern const device_t voodoo_3_3000_agp_device; +extern const device_t voodoo_3_3500_agp_ntsc_device; +extern const device_t voodoo_3_3500_agp_pal_device; +extern const device_t compaq_voodoo_3_3500_agp_device; +extern const device_t voodoo_3_3500_se_agp_device; +extern const device_t voodoo_3_3500_si_agp_device; extern const device_t velocity_100_agp_device; +extern const device_t velocity_200_agp_device; /* Wyse 700 */ extern const device_t wy700_device; diff --git a/src/include/86box/win.h b/src/include/86box/win.h index bb92f265b..3174e24b2 100644 --- a/src/include/86box/win.h +++ b/src/include/86box/win.h @@ -104,7 +104,8 @@ extern "C" { extern HINSTANCE hinstance; extern HWND hwndMain, - hwndRender; + hwndRender, + hwndRender2; extern HANDLE ghMutex; extern HICON hIcon[256]; extern int dpi; @@ -147,9 +148,9 @@ extern int win_get_system_metrics(int i, int dpi); extern LPARAM win_get_string(int id); -extern void win_clear_icon_set(); -extern void win_system_icon_set(); -extern void win_load_icon_set(); +extern void win_clear_icon_set(void); +extern void win_system_icon_set(void); +extern void win_load_icon_set(void); extern void win_get_icons_path(char *path_root); extern intptr_t fdd_type_to_icon(int type); @@ -208,7 +209,7 @@ extern int MediaMenuHandler(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar /* Functions in win_toolbar.c */ extern HWND hwndRebar; extern void ToolBarCreate(HWND hwndParent, HINSTANCE hInst); -extern void ToolBarLoadIcons(); +extern void ToolBarLoadIcons(void); extern void ToolBarUpdatePause(int paused); /* Functions in win_dialog.c: */ @@ -222,8 +223,8 @@ extern int file_dlg_st(HWND hwnd, int i, char *fn, char *title, int save); extern wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title); /* Functions in win_media_menu.c */ -extern void media_menu_init(); -extern void media_menu_reset(); +extern void media_menu_init(void); +extern void media_menu_reset(void); extern int media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); extern HMENU media_menu_get_cassette(void); extern HMENU media_menu_get_cartridge(int id); @@ -240,7 +241,7 @@ extern void media_menu_update_mo(int id); /* Functions in win_ui.c */ extern HMENU menuMain; -extern void ResetAllMenus(); +extern void ResetAllMenus(void); #ifdef __cplusplus } diff --git a/src/include/86box/win_opengl_glslp.h b/src/include/86box/win_opengl_glslp.h index 83c14aaf9..caf86a04f 100644 --- a/src/include/86box/win_opengl_glslp.h +++ b/src/include/86box/win_opengl_glslp.h @@ -19,6 +19,6 @@ #include GLuint load_custom_shaders(const char *path); -GLuint load_default_shaders(); +GLuint load_default_shaders(void); #endif /*!WIN_OPENGL_GLSLP_H*/ diff --git a/src/include/86box/zip.h b/src/include/86box/zip.h index 46745ff06..910436410 100644 --- a/src/include/86box/zip.h +++ b/src/include/86box/zip.h @@ -113,7 +113,7 @@ extern void zip_hard_reset(void); extern void zip_reset(scsi_common_t *sc); extern int zip_load(zip_t *dev, char *fn); -extern void zip_close(); +extern void zip_close(void); #ifdef __cplusplus } diff --git a/src/include/fdi2raw.h b/src/include/fdi2raw.h index 8f71679a8..7a53d9d17 100644 --- a/src/include/fdi2raw.h +++ b/src/include/fdi2raw.h @@ -21,7 +21,7 @@ #ifndef __FDI2RAW_H #define __FDI2RAW_H -#define uae_u8 uint8_t +#define uae_u8 uint8_t #define uae_u16 uint16_t #define uae_u32 uint32_t @@ -32,20 +32,20 @@ typedef struct fdi FDI; extern "C" { #endif -extern int fdi2raw_loadtrack (FDI*, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffset, int *multirev, int mfm); +extern int fdi2raw_loadtrack(FDI *, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffset, int *multirev, int mfm); -extern int fdi2raw_loadrevolution (FDI*, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int mfm); +extern int fdi2raw_loadrevolution(FDI *, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int mfm); extern FDI *fdi2raw_header(FILE *f); -extern void fdi2raw_header_free (FDI *); -extern int fdi2raw_get_last_track(FDI *); -extern int fdi2raw_get_num_sector (FDI *); -extern int fdi2raw_get_last_head(FDI *); -extern int fdi2raw_get_type (FDI *); -extern int fdi2raw_get_bit_rate (FDI *); -extern int fdi2raw_get_rotation (FDI *); -extern int fdi2raw_get_write_protect (FDI *); -extern int fdi2raw_get_tpi (FDI *); +extern void fdi2raw_header_free(FDI *); +extern int fdi2raw_get_last_track(FDI *); +extern int fdi2raw_get_num_sector(FDI *); +extern int fdi2raw_get_last_head(FDI *); +extern int fdi2raw_get_type(FDI *); +extern int fdi2raw_get_bit_rate(FDI *); +extern int fdi2raw_get_rotation(FDI *); +extern int fdi2raw_get_write_protect(FDI *); +extern int fdi2raw_get_tpi(FDI *); #ifdef __cplusplus } diff --git a/src/include/tinyglib.h b/src/include/tinyglib.h index 202bf2d7a..b6cea2989 100644 --- a/src/include/tinyglib.h +++ b/src/include/tinyglib.h @@ -1,115 +1,113 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Minimal reimplementation of GLib for libslirp. + * Minimal reimplementation of GLib for libslirp. * * * - * Author: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #ifndef TINYGLIB_H -# define TINYGLIB_H +#define TINYGLIB_H /* Define this to bypass TinyGLib and use full GLib instead. */ #ifdef TINYGLIB_USE_GLIB -#include +# include #else -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> - +# include +# include +# include +# include +# define HAVE_STDARG_H +# include <86box/86box.h> /* Definitions */ -#define G_LITTLE_ENDIAN 1234 -#define G_BIG_ENDIAN 4321 -#define G_PDP_ENDIAN 3412 -#ifdef __BYTE_ORDER__ -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define G_BYTE_ORDER G_LITTLE_ENDIAN -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define G_BYTE_ORDER G_BIG_ENDIAN -# elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ -# define G_BYTE_ORDER G_PDP_ENDIAN -# endif -#endif -#ifndef G_BYTE_ORDER +# define G_LITTLE_ENDIAN 1234 +# define G_BIG_ENDIAN 4321 +# define G_PDP_ENDIAN 3412 +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define G_BYTE_ORDER G_LITTLE_ENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define G_BYTE_ORDER G_BIG_ENDIAN +# elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ +# define G_BYTE_ORDER G_PDP_ENDIAN +# endif +# endif +# ifndef G_BYTE_ORDER /* Safe to assume LE for MSVC, as Windows is LE on all architectures. */ -# define G_BYTE_ORDER G_LITTLE_ENDIAN -#endif +# define G_BYTE_ORDER G_LITTLE_ENDIAN +# endif -#ifdef _WIN32 -# define G_OS_WIN32 1 -#else -# define G_OS_UNIX 1 -#endif +# ifdef _WIN32 +# define G_OS_WIN32 1 +# else +# define G_OS_UNIX 1 +# endif -#define G_SPAWN_SEARCH_PATH 0 - -#if defined(__LP64__) || defined(__LLP64__) || defined(_WIN64) -# define GLIB_SIZEOF_VOID_P 8 -# if defined(__LLP64__) || defined(_WIN64) -# define GLIB_SIZEOF_LONG 4 -# else -# define GLIB_SIZEOF_LONG 8 -# endif -# define GLIB_SIZEOF_SIZE_T 8 -# define GLIB_SIZEOF_SSIZE_T 8 -#else -# define GLIB_SIZEOF_VOID_P 4 -# define GLIB_SIZEOF_LONG 4 -# define GLIB_SIZEOF_SIZE_T 4 -# define GLIB_SIZEOF_SSIZE_T 4 -#endif +# define G_SPAWN_SEARCH_PATH 0 +# if defined(__LP64__) || defined(__LLP64__) || defined(_WIN64) +# define GLIB_SIZEOF_VOID_P 8 +# if defined(__LLP64__) || defined(_WIN64) +# define GLIB_SIZEOF_LONG 4 +# else +# define GLIB_SIZEOF_LONG 8 +# endif +# define GLIB_SIZEOF_SIZE_T 8 +# define GLIB_SIZEOF_SSIZE_T 8 +# else +# define GLIB_SIZEOF_VOID_P 4 +# define GLIB_SIZEOF_LONG 4 +# define GLIB_SIZEOF_SIZE_T 4 +# define GLIB_SIZEOF_SSIZE_T 4 +# endif /* Types */ /* Windows does not define ssize_t, so we need to define it here. */ -#ifndef _SSIZE_T_DEFINED -# define _SSIZE_T_DEFINED -# undef ssize_t -# ifdef _WIN64 -# define ssize_t int64_t -# else -# define ssize_t int32_t -# endif -#endif +# ifndef _SSIZE_T_DEFINED +# define _SSIZE_T_DEFINED +# undef ssize_t +# ifdef _WIN64 +# define ssize_t int64_t +# else +# define ssize_t int32_t +# endif +# endif -#define gboolean int -#define gchar char -#define gint int -#define gint16 int16_t -#define gint32 int32_t -#define gint64 int64_t -#define glong long -#define GPid void * -#define gpointer void * -#define gsize size_t -#define GSpawnFlags void * -#define GSpawnChildSetupFunc void * -#define gssize ssize_t -#define GString char -#define GStrv char ** -#define guint unsigned int -#define guint16 uint16_t -#define guint32 uint32_t -#define guint64 uint64_t +# define gboolean int +# define gchar char +# define gint int +# define gint16 int16_t +# define gint32 int32_t +# define gint64 int64_t +# define glong long +# define GPid void * +# define gpointer void * +# define gsize size_t +# define GSpawnFlags void * +# define GSpawnChildSetupFunc void * +# define gssize ssize_t +# define GString char +# define GStrv char ** +# define guint unsigned int +# define guint16 uint16_t +# define guint32 uint32_t +# define guint64 uint64_t typedef struct _GDebugKey { char key[32]; - int val; + int val; } GDebugKey; typedef struct _GError { @@ -120,80 +118,86 @@ typedef struct _GRand { uint8_t dummy; } GRand; - /* Functions */ -extern gboolean g_spawn_async_with_fds(const gchar *working_directory, gchar **argv, +extern gboolean g_spawn_async_with_fds(const gchar *working_directory, gchar **argv, gchar **envp, GSpawnFlags flags, GSpawnChildSetupFunc child_setup, gpointer user_data, GPid *child_pid, gint stdin_fd, gint stdout_fd, gint stderr_fd, GError **error); -extern GString *g_string_new(gchar *base); -extern gchar *g_string_free(GString *string, gboolean free_segment); -extern gchar *g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle); -extern guint g_strv_length(gchar **str_array); - +extern GString *g_string_new(gchar *base); +extern gchar *g_string_free(GString *string, gboolean free_segment); +extern gchar *g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle); +extern guint g_strv_length(gchar **str_array); /* Macros */ -#define tinyglib_pclog(f, s, ...) pclog("TinyGLib " f "(): " s "\n", ##__VA_ARGS__) +# define tinyglib_pclog(f, s, ...) pclog("TinyGLib " f "(): " s "\n", ##__VA_ARGS__) -#define GLIB_CHECK_VERSION(a, b, c) 1 -#ifdef __GNUC__ -# define G_GNUC_PRINTF(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) -#else -# define G_GNUC_PRINTF(format_idx, arg_idx) -#endif -#define G_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) -#define G_STATIC_ASSERT(e) /* this should probably do something */ -#define G_UNLIKELY(e) (e) - -#define g_assert(e) do { if (!(e)) fatal("TinyGLib g_assert(" #e ")\n"); } while (0) -#ifdef __GNUC__ -# define g_assert_not_reached __builtin_unreachable -#else -# ifdef _MSC_VER -# define g_assert_not_reached() __assume(0) -# else -# define g_assert_not_reached() -# endif -#endif -#define g_critical(s, ...) fatal("TinyGLib g_critical(): " s "\n", ##__VA_ARGS__) -#ifdef TINYGLIB_DEBUG -# define g_debug(s, ...) tinyglib_pclog("g_debug", s, ##__VA_ARGS__) -#else -# define g_debug(s, ...) -#endif -#define g_error(s, ...) tinyglib_pclog("g_error", s, ##__VA_ARGS__) -#define g_error_free(err) -#define g_malloc0(s) calloc(1, s) -#define g_new(t, n) (t *) malloc(sizeof(t) * n) -#define g_new0(t, n) (t *) calloc(n, sizeof(t)) -#ifdef TINYGLIB_DEBUG -# define g_parse_debug_string(s, k, n) ((!!sizeof(k)) * -1) /* unimplemented; always enables all debug flags */ -#else -# define g_parse_debug_string(s, k, n) (!sizeof(k)) -#endif -#define g_rand_int_range(r, min, max) (rand() % (max + 1 - min) + min) -#define g_rand_new() calloc(1, sizeof(GRand)) -#define g_return_val_if_fail(e, v) if (!(e)) return (v) -#define g_shell_parse_argv(a, b, c, d) !!(sizeof(b)) /* unimplemented */ -#define g_strdup(str) ((str) ? strdup(str) : NULL) -#define g_warn_if_fail(e) do { if (!(e)) pclog("TinyGLib g_warn_if_fail(" #e ")\n"); } while (0) -#define g_warn_if_reached() pclog("TinyGLib g_warn_if_reached()\n") -#define g_warning(s, ...) tinyglib_pclog("g_warning", s, ##__VA_ARGS__) +# define GLIB_CHECK_VERSION(a, b, c) 1 +# ifdef __GNUC__ +# define G_GNUC_PRINTF(format_idx, arg_idx) __attribute__((__format__(__printf__, format_idx, arg_idx))) +# else +# define G_GNUC_PRINTF(format_idx, arg_idx) +# endif +# define G_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) +# define G_STATIC_ASSERT(e) /* this should probably do something */ +# define G_UNLIKELY(e) (e) +# define g_assert(e) \ + do { \ + if (!(e)) \ + fatal("TinyGLib g_assert(" #e ")\n"); \ + } while (0) +# ifdef __GNUC__ +# define g_assert_not_reached __builtin_unreachable +# else +# ifdef _MSC_VER +# define g_assert_not_reached() __assume(0) +# else +# define g_assert_not_reached() +# endif +# endif +# define g_critical(s, ...) fatal("TinyGLib g_critical(): " s "\n", ##__VA_ARGS__) +# ifdef TINYGLIB_DEBUG +# define g_debug(s, ...) tinyglib_pclog("g_debug", s, ##__VA_ARGS__) +# else +# define g_debug(s, ...) +# endif +# define g_error(s, ...) tinyglib_pclog("g_error", s, ##__VA_ARGS__) +# define g_error_free(err) +# define g_malloc0(s) calloc(1, s) +# define g_new(t, n) (t *) malloc(sizeof(t) * n) +# define g_new0(t, n) (t *) calloc(n, sizeof(t)) +# ifdef TINYGLIB_DEBUG +# define g_parse_debug_string(s, k, n) ((!!sizeof(k)) * -1) /* unimplemented; always enables all debug flags */ +# else +# define g_parse_debug_string(s, k, n) (!sizeof(k)) +# endif +# define g_rand_int_range(r, min, max) (rand() % (max + 1 - min) + min) +# define g_rand_new() calloc(1, sizeof(GRand)) +# define g_return_val_if_fail(e, v) \ + if (!(e)) \ + return (v) +# define g_shell_parse_argv(a, b, c, d) !!(sizeof(b)) /* unimplemented */ +# define g_strdup(str) ((str) ? strdup(str) : NULL) +# define g_warn_if_fail(e) \ + do { \ + if (!(e)) \ + pclog("TinyGLib g_warn_if_fail(" #e ")\n"); \ + } while (0) +# define g_warn_if_reached() pclog("TinyGLib g_warn_if_reached()\n") +# define g_warning(s, ...) tinyglib_pclog("g_warning", s, ##__VA_ARGS__) /* Remapped functions */ -#define g_free free -#define g_getenv getenv -#define g_malloc malloc -#define g_rand_free free -#define g_realloc realloc -#define g_snprintf snprintf -#define g_strerror strerror -#define g_strfreev free -#define g_string_append_printf sprintf /* unimplemented */ -#define g_vsnprintf vsnprintf - +# define g_free free +# define g_getenv getenv +# define g_malloc malloc +# define g_rand_free free +# define g_realloc realloc +# define g_snprintf snprintf +# define g_strerror strerror +# define g_strfreev free +# define g_string_append_printf sprintf /* unimplemented */ +# define g_vsnprintf vsnprintf #endif diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index 098c120f0..e4792969c 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -1,47 +1,49 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Definitions for project version, branding, and external links. + * Definitions for project version, branding, and external links. * - * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. */ #define _LSTR(s) L ## s #define LSTR(s) _LSTR(s) /* Version info. */ -#define EMU_NAME "86Box" -#define EMU_NAME_W LSTR(EMU_NAME) +#define EMU_NAME "86Box" +#define EMU_NAME_W LSTR(EMU_NAME) -#define EMU_VERSION "3.8" -#define EMU_VERSION_W LSTR(EMU_VERSION) -#define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ -#define EMU_VERSION_MAJ 3 -#define EMU_VERSION_MIN 8 +#define EMU_VERSION "3.11" +#define EMU_VERSION_W LSTR(EMU_VERSION) +#define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ +#define EMU_VERSION_MAJ 3 +#define EMU_VERSION_MIN 11 #define EMU_VERSION_PATCH 0 -#define EMU_BUILD_NUM 0 +#define EMU_BUILD_NUM 0 -#define EMU_VERSION_FULL EMU_VERSION -#define EMU_VERSION_FULL_W EMU_VERSION_W +#define EMU_VERSION_FULL EMU_VERSION +#define EMU_VERSION_FULL_W EMU_VERSION_W -#define COPYRIGHT_YEAR "2022" +#define COPYRIGHT_YEAR "2022" /* Web URL info. */ -#define EMU_SITE "86box.net" -#define EMU_SITE_W LSTR(EMU_SITE) -#define EMU_ROMS_URL "https://github.com/86Box/roms/releases/latest" -#define EMU_ROMS_URL_W LSTR(EMU_ROMS_URL) +#define EMU_SITE "86box.net" +#define EMU_SITE_W LSTR(EMU_SITE) +#define EMU_ROMS_URL "https://github.com/86Box/roms/releases/latest" +#define EMU_ROMS_URL_W LSTR(EMU_ROMS_URL) #ifdef RELEASE_BUILD -# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.8/" +# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.11/" #else -# define EMU_DOCS_URL "https://86box.readthedocs.io" +# define EMU_DOCS_URL "https://86box.readthedocs.io" #endif -#define EMU_DOCS_URL_W LSTR(EMU_DOCS_URL) +#define EMU_DOCS_URL_W LSTR(EMU_DOCS_URL) diff --git a/src/ini.c b/src/ini.c index 923d50ca9..59a3dc629 100644 --- a/src/ini.c +++ b/src/ini.c @@ -1,29 +1,29 @@ /* * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Configuration file handler. + * Configuration file handler. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Overdoze, - * David Hrdlička, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Overdoze, + * David Hrdlička, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2018,2019 David Hrdlička. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2018,2019 David Hrdlička. * * NOTE: Forcing config files to be in Unicode encoding breaks - * it on Windows XP, and possibly also Vista. Use the - * -DANSI_CFG for use on these systems. + * it on Windows XP, and possibly also Vista. Use the + * -DANSI_CFG for use on these systems. */ #include @@ -141,7 +141,7 @@ ini_rename_section(ini_section_t section, char *name) } static entry_t * -find_entry(section_t *section, char *name) +find_entry(section_t *section, const char *name) { entry_t *ent; @@ -222,7 +222,7 @@ ini_find_or_create_section(ini_t ini, char *name) } static entry_t * -create_entry(section_t *section, char *name) +create_entry(section_t *section, const char *name) { entry_t *ne = malloc(sizeof(entry_t)); @@ -492,7 +492,7 @@ ini_write(ini_t ini, char *fn) } ini_t -ini_new() +ini_new(void) { ini_t ini = malloc(sizeof(list_t)); memset(ini, 0, sizeof(list_t)); @@ -750,7 +750,7 @@ ini_section_set_mac(ini_section_t self, char *name, int val) } void -ini_section_set_string(ini_section_t self, char *name, char *val) +ini_section_set_string(ini_section_t self, const char *name, const char *val) { section_t *section = (section_t *) self; entry_t *ent; diff --git a/src/ioapic.c b/src/ioapic.c index 587b3699d..7d1a62cca 100644 --- a/src/ioapic.c +++ b/src/ioapic.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Skeleton I/O APIC implementation, currently housing the MPS - * table patcher for machines that require it. + * Skeleton I/O APIC implementation, currently housing the MPS + * table patcher for machines that require it. * * * - * Author: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include diff --git a/src/log.c b/src/log.c index 9eb80c6ad..e36ab69f9 100644 --- a/src/log.c +++ b/src/log.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * The handler of the new logging system. + * The handler of the new logging system. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2021 Miran Grca. - * Copyright 2021 Fred N. van Kempen. + * Copyright 2021 Miran Grca. + * Copyright 2021 Fred N. van Kempen. */ #include #include diff --git a/src/lpt.c b/src/lpt.c index 269546c5d..b20b25641 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -40,9 +40,9 @@ static const struct { {"dot_matrix", &lpt_prt_escp_device }, {"postscript", &lpt_prt_ps_device }, {"plip", &lpt_plip_device }, - {"dongle_savquest", &lpt_hasp_savquest_device }, + {"dongle_savquest", &lpt_hasp_savquest_device }, {"", NULL } -// clang-format on + // clang-format on }; char * diff --git a/src/mac/CMakeLists.txt b/src/mac/CMakeLists.txt index 2fdc2363a..9ad6206a8 100644 --- a/src/mac/CMakeLists.txt +++ b/src/mac/CMakeLists.txt @@ -1,20 +1,20 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: dob205, -# Jerome Vernet -# David Hrdlička, +# Authors: dob205, +# Jerome Vernet +# David Hrdlička, # -# Copyright 2021 dob205. -# Copyright 2021 Jerome Vernet. -# Copyright 2021 David Hrdlička. +# Copyright 2021 dob205. +# Copyright 2021 Jerome Vernet. +# Copyright 2021 David Hrdlička. # # Pick the bundle icon depending on the release channel diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index c96747f47..1f356a91d 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(mch OBJECT machine.c machine_table.c m_xt.c m_xt_compaq.c diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 17125d89c..5d64bda3b 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -1,45 +1,45 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the Amstrad series of PC's: PC1512, PC1640 and - * PC200, including their keyboard, mouse and video devices, as - * well as the PC2086 and PC3086 systems. + * Emulation of the Amstrad series of PC's: PC1512, PC1640 and + * PC200, including their keyboard, mouse and video devices, as + * well as the PC2086 and PC3086 systems. * - * PC1512: The PC1512 extends CGA with a bit-planar 640x200x16 mode. - * Most CRTC registers are fixed. + * PC1512: The PC1512 extends CGA with a bit-planar 640x200x16 mode. + * Most CRTC registers are fixed. * - * The Technical Reference Manual lists the video waitstate - * time as between 12 and 46 cycles. We currently always use - * the lower number. + * The Technical Reference Manual lists the video waitstate + * time as between 12 and 46 cycles. We currently always use + * the lower number. * - * PC1640: Mostly standard EGA, but with CGA & Hercules emulation. + * PC1640: Mostly standard EGA, but with CGA & Hercules emulation. * - * PC200: CGA with some NMI stuff. But we don't need that as it's only - * used for TV and LCD displays, and we're emulating a CRT. + * PC200: CGA with some NMI stuff. But we don't need that as it's only + * used for TV and LCD displays, and we're emulating a CRT. * - * PPC512/640: Portable with both CGA-compatible and MDA-compatible monitors. + * PPC512/640: Portable with both CGA-compatible and MDA-compatible monitors. * - * TODO: This module is not complete yet: + * TODO: This module is not complete yet: * - * All models: The internal mouse controller does not work correctly with - * version 7.04 of the mouse driver. + * All models: The internal mouse controller does not work correctly with + * version 7.04 of the mouse driver. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * John Elliott, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * John Elliott, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2019 John Elliott. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2019 John Elliott. */ #include #include @@ -162,10 +162,10 @@ static uint8_t key_queue[16]; static int key_queue_start = 0, key_queue_end = 0; static uint8_t crtc_mask[32] = { - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, - 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, + 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static video_timings_t timing_pc1512 = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*PC1512 video code handles waitstates itself*/ @@ -2551,7 +2551,7 @@ machine_amstrad_init(const machine_t *model, int type) ms_read, NULL, NULL, ms_write, NULL, NULL, ams); if (mouse_type == MOUSE_TYPE_INTERNAL) { -/* Tell mouse driver about our internal mouse. */ + /* Tell mouse driver about our internal mouse. */ mouse_reset(); mouse_set_buttons(2); mouse_set_poll(ms_poll, ams); diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index a07e981df..7cfec3735 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of 286 and 386SX machines. + * Implementation of 286 and 386SX machines. * * * - * Authors: Sarah Walker, - * Miran Grca, - * EngiNerd + * Authors: Sarah Walker, + * Miran Grca, + * EngiNerd * - * Copyright 2010-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2020 EngiNerd. + * Copyright 2010-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2020 EngiNerd. */ #include #include diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 4d0b27b98..1343b38ad 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of 386DX and 486 machines. + * Implementation of 386DX and 486 machines. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2010-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2010-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include diff --git a/src/machine/m_at_commodore.c b/src/machine/m_at_commodore.c index a83fda08e..8eeabab19 100644 --- a/src/machine/m_at_commodore.c +++ b/src/machine/m_at_commodore.c @@ -84,7 +84,7 @@ cbm_io_write(uint16_t port, uint8_t val, void *p) } static void -cbm_io_init() +cbm_io_init(void) { io_sethandler(0x0230, 0x0001, NULL, NULL, NULL, cbm_io_write, NULL, NULL, NULL); } diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 2b22002dc..74e853834 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of various Compaq PC's. + * Emulation of various Compaq PC's. * * * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -702,7 +702,7 @@ const device_config_t compaq_plasma_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t compaq_plasma_device = { diff --git a/src/machine/m_at_misc.c b/src/machine/m_at_misc.c index ca1c78042..71c9d2ab7 100644 --- a/src/machine/m_at_misc.c +++ b/src/machine/m_at_misc.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Miscellaneous, Fake, Hypervisor machines. + * Implementation of Miscellaneous, Fake, Hypervisor machines. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2019 Miran Grca. + * Copyright 2016-2019 Miran Grca. */ #include #include diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index daa831e7d..fd91067ae 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Slot 2 machines. + * Implementation of Slot 2 machines. * - * Slot 2 is quite a rare type of Slot. Used mostly by Pentium II & III Xeons + * Slot 2 is quite a rare type of Slot. Used mostly by Pentium II & III Xeons * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2019 Miran Grca. + * Copyright 2016-2019 Miran Grca. */ #include #include diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index a5bff87d7..d24933ff9 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Socket 4 machines. + * Implementation of Socket 4 machines. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2010-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2010-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index c0c18f3c7..55751ae43 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Socket 5 machines. + * Implementation of Socket 5 machines. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2010-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2010-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 3a7505a38..09b142c83 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -1,22 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Socket 7 (Single Voltage) machines. + * Implementation of Socket 7 (Single Voltage) machines. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, - * - * Copyright 2010-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Authors: Sarah Walker, + * Miran Grca, + * Melissa Goad, * + * Copyright 2010-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 1a1618dc0..5ffbec822 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Socket 8 machines. + * Implementation of Socket 8 machines. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2019 Miran Grca. + * Copyright 2016-2019 Miran Grca. */ #include #include diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 1dbba3715..381940a10 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Super Socket 7 machines. + * Implementation of Super Socket 7 machines. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, + * Authors: Sarah Walker, + * Miran Grca, + * Melissa Goad, * - * Copyright 2010-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2020 Melissa Goad. + * Copyright 2010-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2020 Melissa Goad. */ #include #include diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index dbfcb2604..6b09b1e02 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -169,7 +169,7 @@ extern uint8_t *ram; /* Physical RAM */ -void at_init(); +void at_init(void); /* The T3100e motherboard can (and does) dynamically reassign RAM between * conventional, XMS and EMS. This translates to monkeying with the mappings. @@ -336,7 +336,7 @@ port_to_page(uint16_t addr) } /* Used to dump the memory mapping table, for debugging -void dump_mappings() +void dump_mappings(void) { mem_mapping_t *mm = base_mapping.next; diff --git a/src/machine/m_at_t3100e_vid.c b/src/machine/m_at_t3100e_vid.c index 7579f3892..30bbc488b 100644 --- a/src/machine/m_at_t3100e_vid.c +++ b/src/machine/m_at_t3100e_vid.c @@ -102,7 +102,7 @@ t3100e_display_set(uint8_t internal) } uint8_t -t3100e_display_get() +t3100e_display_get(void) { return st_display_internal; } diff --git a/src/machine/m_elt.c b/src/machine/m_elt.c index be0e26cb3..47e6f145d 100644 --- a/src/machine/m_elt.c +++ b/src/machine/m_elt.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Epson Equity LT portable computer emulation. + * Epson Equity LT portable computer emulation. * - * Author: Lubomir Rintel, + * Authors: Lubomir Rintel, * - * Copyright 2022 Lubomir Rintel. + * Copyright 2022 Lubomir Rintel. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index 2fdbc852f..3f78c8f49 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -1,83 +1,83 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Schneider EuroPC system. + * Implementation of the Schneider EuroPC system. * - * NOTES: BIOS info (taken from MAME, thanks guys!!) + * NOTES: BIOS info (taken from MAME, thanks guys!!) * - * f000:e107 bios checksum test - * memory test - * f000:e145 irq vector init - * f000:e156 - * f000:e169-d774 test of special registers 254/354 - * f000:e16c-e817 - * f000:e16f - * f000:ec08 test of special registers 800a rtc time - * or date error, rtc corrected - * f000:ef66 0xf - * f000:db3e 0x8..0xc - * f000:d7f8 - * f000:db5f - * f000:e172 - * f000:ecc5 801a video setup error - * f000:d6c9 copyright output - * f000:e1b7 - * f000:e1be DI bits set mean output text!!! (801a) - * f000: 0x8000 output - * 1 rtc error - * 2 rtc time or date error - * 4 checksum error in setup - * 8 rtc status corrected - * 10 video setup error - * 20 video ram bad - * 40 monitor type not recogniced - * 80 mouse port enabled - * 100 joystick port enabled - * f000:e1e2-dc0c CPU speed is 4.77 mhz - * f000:e1e5-f9c0 keyboard processor error - * f000:e1eb-c617 external lpt1 at 0x3bc - * f000:e1ee-e8ee external coms at + * f000:e107 bios checksum test + * memory test + * f000:e145 irq vector init + * f000:e156 + * f000:e169-d774 test of special registers 254/354 + * f000:e16c-e817 + * f000:e16f + * f000:ec08 test of special registers 800a rtc time + * or date error, rtc corrected + * f000:ef66 0xf + * f000:db3e 0x8..0xc + * f000:d7f8 + * f000:db5f + * f000:e172 + * f000:ecc5 801a video setup error + * f000:d6c9 copyright output + * f000:e1b7 + * f000:e1be DI bits set mean output text!!! (801a) + * f000: 0x8000 output + * 1 rtc error + * 2 rtc time or date error + * 4 checksum error in setup + * 8 rtc status corrected + * 10 video setup error + * 20 video ram bad + * 40 monitor type not recogniced + * 80 mouse port enabled + * 100 joystick port enabled + * f000:e1e2-dc0c CPU speed is 4.77 mhz + * f000:e1e5-f9c0 keyboard processor error + * f000:e1eb-c617 external lpt1 at 0x3bc + * f000:e1ee-e8ee external coms at * - * Routines: - * f000:c92d output text at bp - * f000:db3e RTC read reg cl - * f000:e8ee piep - * f000:e95e RTC write reg cl - * polls until JIM 0xa is zero, - * output cl at jim 0xa - * write ah hinibble as lownibble into jim 0xa - * write ah lownibble into jim 0xa - * f000:ef66 RTC read reg cl - * polls until jim 0xa is zero, - * output cl at jim 0xa - * read low 4 nibble at jim 0xa - * read low 4 nibble at jim 0xa - * return first nibble<<4|second nibble in ah - * f000:f046 seldom compares ret - * f000:fe87 0 -> ds + * Routines: + * f000:c92d output text at bp + * f000:db3e RTC read reg cl + * f000:e8ee piep + * f000:e95e RTC write reg cl + * polls until JIM 0xa is zero, + * output cl at jim 0xa + * write ah hinibble as lownibble into jim 0xa + * write ah lownibble into jim 0xa + * f000:ef66 RTC read reg cl + * polls until jim 0xa is zero, + * output cl at jim 0xa + * read low 4 nibble at jim 0xa + * read low 4 nibble at jim 0xa + * return first nibble<<4|second nibble in ah + * f000:f046 seldom compares ret + * f000:fe87 0 -> ds * - * Memory: - * 0000:0469 bit 0: b0000 memory available - * bit 1: b8000 memory available - * 0000:046a: 00 jim 250 01 jim 350 + * Memory: + * 0000:0469 bit 0: b0000 memory available + * bit 1: b8000 memory available + * 0000:046a: 00 jim 250 01 jim 350 * - * WARNING THIS IS A WORK-IN-PROGRESS MODULE. USE AT OWN RISK. + * WARNING THIS IS A WORK-IN-PROGRESS MODULE. USE AT OWN RISK. * * * - * Author: Fred N. van Kempen, + * Authors: Fred N. van Kempen, * - * Inspired by the "jim.c" file originally present, but a - * fully re-written module, based on the information from - * Schneider's schematics and technical manuals, and the - * input from people with real EuroPC hardware. + * Inspired by the "jim.c" file originally present, but a + * fully re-written module, based on the information from + * Schneider's schematics and technical manuals, and the + * input from people with real EuroPC hardware. * - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 0418dfa4c..6446d5852 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the IBM PCjr. + * Emulation of the IBM PCjr. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 8b18dbf02..53e6928e8 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -1,36 +1,36 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the IBM PS/1 models 2011, 2121. + * Emulation of the IBM PS/1 models 2011, 2121. * - * Model 2011: The initial model, using a 10MHz 80286. + * Model 2011: The initial model, using a 10MHz 80286. * - * Model 2121: This is similar to model 2011 but some of the functionality - * has moved to a chip at ports 0xe0 (index)/0xe1 (data). The - * only functions I have identified are enables for the first - * 512K and next 128K of RAM, in bits 0 of registers 0 and 1 - * respectively. + * Model 2121: This is similar to model 2011 but some of the functionality + * has moved to a chip at ports 0xe0 (index)/0xe1 (data). The + * only functions I have identified are enables for the first + * 512K and next 128K of RAM, in bits 0 of registers 0 and 1 + * respectively. * - * Port 0x105 has bit 7 forced high. Without this 128K of - * memory will be missed by the BIOS on cold boots. + * Port 0x105 has bit 7 forced high. Without this 128K of + * memory will be missed by the BIOS on cold boots. * - * The reserved 384K is remapped to the top of extended memory. - * If this is not done then you get an error on startup. + * The reserved 384K is remapped to the top of extended memory. + * If this is not done then you get an error on startup. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 4a3139a03..90c69aa3c 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -806,7 +806,7 @@ ps2_mca_write(uint16_t port, uint8_t val, void *p) } static void -ps2_mca_board_common_init() +ps2_mca_board_common_init(void) { io_sethandler(0x0091, 0x0001, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); io_sethandler(0x0094, 0x0001, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 18c5652ad..c7789de26 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of Tandy models 1000, 1000HX and 1000SL2. + * Emulation of Tandy models 1000, 1000HX and 1000SL2. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include diff --git a/src/machine/m_v86p.c b/src/machine/m_v86p.c index 5f115dab3..03bfda842 100644 --- a/src/machine/m_v86p.c +++ b/src/machine/m_v86p.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Victor V86P portable computer emulation. + * Victor V86P portable computer emulation. * - * Author: Lubomir Rintel, + * Authors: Lubomir Rintel, * - * Copyright 2021 Lubomir Rintel. + * Copyright 2021 Lubomir Rintel. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index a58f9c97d..8f2bec8bd 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -336,26 +336,25 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.BIN", 0x000fe000, 65536, 0); - if (ret) - { + if (ret) { bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F400.BIN", - 0x000f4000, 8192, 0); + 0x000f4000, 8192, 0); bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F600.BIN", - 0x000f6000, 8192, 0); + 0x000f6000, 8192, 0); bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_FA00.BIN", - 0x000fa000, 8192, 0); + 0x000fa000, 8192, 0); bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F800.BIN", - 0x000f8000, 8192, 0); + 0x000f8000, 8192, 0); bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_FC00.BIN", - 0x000fc000, 8192, 0); + 0x000fc000, 8192, 0); } if (bios_only || !ret) - return ret; + return ret; device_add(&keyboard_pravetz_device); @@ -367,13 +366,13 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) int machine_xt_micoms_xl7turbo_init(const machine_t *model) { - int ret; - + int ret; + ret = bios_load_linear("roms/machines/mxl7t/XL7_TURBO.BIN", - 0x000fe000, 8192, 0); + 0x000fe000, 8192, 0); if (bios_only || !ret) - return ret; + return ret; machine_xt_init_ex(model); return ret; @@ -602,14 +601,14 @@ machine_xt_v20xt_init(const machine_t *model) int ret; ret = bios_load_linear("roms/machines/v20xt/V20XTBios.bin", - 0x000fe000, 8192, 0); + 0x000fe000, 8192, 0); if (bios_only || !ret) - return ret; + return ret; machine_xt_clone_init(model); - return ret; + return ret; } int diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index d66c15eaf..733063306 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of various Compaq XT-class PC's. + * Emulation of various Compaq XT-class PC's. * * * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index d9117787e..c978e2caf 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -1,27 +1,26 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the Olivetti XT-compatible machines. + * Emulation of the Olivetti XT-compatible machines. * - * - Supports MM58174 real-time clock emulation (M24) - * - Supports MM58274 real-time clock emulation (M240) + * - Supports MM58174 real-time clock emulation (M24) + * - Supports MM58274 real-time clock emulation (M240) * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * EngiNerd + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * EngiNerd * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2020 EngiNerd. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2020 EngiNerd. */ - #include #include #include @@ -29,6 +28,7 @@ #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/timer.h> #include <86box/io.h> @@ -48,6 +48,7 @@ #include <86box/gameport.h> #include <86box/hdc.h> #include <86box/port_6x.h> +#include <86box/serial.h> #include <86box/sound.h> #include <86box/snd_speaker.h> #include <86box/video.h> @@ -73,43 +74,43 @@ #define CGA_COMPOSITE 1 enum MM58174_ADDR { - /* Registers */ - MM58174_TEST, /* TEST register, write only */ - MM58174_TENTHS, /* Tenths of second, read only */ - MM58174_SECOND1, /* Units of seconds, read only */ - MM58174_SECOND10, /* Tens of seconds, read only */ - MM58174_MINUTE1, - MM58174_MINUTE10, - MM58174_HOUR1, - MM58174_HOUR10, - MM58174_DAY1, - MM58174_DAY10, - MM58174_WEEKDAY, - MM58174_MONTH1, - MM58174_MONTH10, - MM58174_LEAPYEAR, /* Leap year status, write only */ - MM58174_RESET, /* RESET register, write only */ - MM58174_IRQ /* Interrupt register, read / write */ + /* Registers */ + MM58174_TEST, /* TEST register, write only */ + MM58174_TENTHS, /* Tenths of second, read only */ + MM58174_SECOND1, /* Units of seconds, read only */ + MM58174_SECOND10, /* Tens of seconds, read only */ + MM58174_MINUTE1, + MM58174_MINUTE10, + MM58174_HOUR1, + MM58174_HOUR10, + MM58174_DAY1, + MM58174_DAY10, + MM58174_WEEKDAY, + MM58174_MONTH1, + MM58174_MONTH10, + MM58174_LEAPYEAR, /* Leap year status, write only */ + MM58174_RESET, /* RESET register, write only */ + MM58174_IRQ /* Interrupt register, read / write */ }; enum MM58274_ADDR { - /* Registers */ - MM58274_CONTROL, /* Control register */ - MM58274_TENTHS, /* Tenths of second, read only */ - MM58274_SECOND1, - MM58274_SECOND10, - MM58274_MINUTE1, - MM58274_MINUTE10, - MM58274_HOUR1, - MM58274_HOUR10, - MM58274_DAY1, - MM58274_DAY10, - MM58274_MONTH1, - MM58274_MONTH10, - MM58274_YEAR1, - MM58274_YEAR10, - MM58274_WEEKDAY, - MM58274_SETTINGS /* Settings register */ + /* Registers */ + MM58274_CONTROL, /* Control register */ + MM58274_TENTHS, /* Tenths of second, read only */ + MM58274_SECOND1, + MM58274_SECOND10, + MM58274_MINUTE1, + MM58274_MINUTE10, + MM58274_HOUR1, + MM58274_HOUR10, + MM58274_DAY1, + MM58274_DAY10, + MM58274_MONTH1, + MM58274_MONTH10, + MM58274_YEAR1, + MM58274_YEAR10, + MM58274_WEEKDAY, + MM58274_SETTINGS /* Settings register */ }; static struct tm intclk; @@ -121,6 +122,7 @@ typedef struct { uint8_t status; uint8_t out; uint8_t output_port; + uint8_t id; int param, param_total; uint8_t params[16]; @@ -146,23 +148,22 @@ video_timings_t timing_m19_vid = { VIDEO_ISA, 8, 16, 32, 8, 16, 32 }; const device_t m19_vid_device; -#ifdef ENABLE_M24VID_LOG -int m24vid_do_log = ENABLE_M24VID_LOG; +#ifdef ENABLE_XT_OLIVETTI_LOG +int xt_olivetti_do_log = ENABLE_XT_OLIVETTI_LOG; static void -m24_log(const char *fmt, ...) +xt_olivetti_log(const char *fmt, ...) { va_list ap; - if (m24vid_do_log) { + if (xt_olivetti_do_log) { va_start(ap, fmt); - vfprintf(stdlog, fmt, ap); + pclog_ex(fmt, ap); va_end(ap); - fflush(stdlog); } } #else -# define m24_log(fmt, ...) +# define xt_olivetti_log(fmt, ...) #endif /* Set the chip time. */ @@ -202,7 +203,7 @@ mm58174_time_get(uint8_t *regs, struct tm *tm) /* One more second has passed, update the internal clock. */ static void -mm58x74_recalc() +mm58x74_recalc(void) { /* Ping the internal clock. */ if (++intclk.tm_sec == 60) { @@ -253,14 +254,14 @@ mm58174_start(nvr_t *nvr) static void mm58174_write(uint16_t addr, uint8_t val, void *priv) { - nvr_t *nvr = (nvr_t *) priv; + nvr_t *nvr = (nvr_t *) priv; addr &= 0x0f; val &= 0x0f; /* Update non-read-only changed values if not synchronizing time to host */ - if ((addr != MM58174_TENTHS) && (addr != MM58174_SECOND1) && (addr != MM58174_SECOND10)) - if ((nvr->regs[addr] != val) && !(time_sync & TIME_SYNC_ENABLED)) + if ((addr != MM58174_TENTHS) && (addr != MM58174_SECOND1) && (addr != MM58174_SECOND10)) + if ((nvr->regs[addr] != val) && !(time_sync & TIME_SYNC_ENABLED)) nvr_dosave = 1; if ((addr == MM58174_RESET) && (val & 0x01)) { @@ -268,7 +269,7 @@ mm58174_write(uint16_t addr, uint8_t val, void *priv) nvr->regs[MM58174_TENTHS] = 0; if (!(time_sync & TIME_SYNC_ENABLED)) { /* Only set seconds to 0 if not synchronizing time to host clock */ - nvr->regs[MM58174_SECOND1] = 0; + nvr->regs[MM58174_SECOND1] = 0; nvr->regs[MM58174_SECOND10] = 0; } } @@ -284,7 +285,7 @@ mm58174_write(uint16_t addr, uint8_t val, void *priv) static uint8_t mm58174_read(uint16_t addr, void *priv) { - nvr_t *nvr = (nvr_t *) priv; + nvr_t *nvr = (nvr_t *) priv; addr &= 0x0f; @@ -333,12 +334,12 @@ mm58174_init(nvr_t *nvr, int size) static void mm58274_time_set(uint8_t *regs, struct tm *tm) { - regs[MM58274_SECOND1] = (tm->tm_sec % 10); - regs[MM58274_SECOND10] = (tm->tm_sec / 10); - regs[MM58274_MINUTE1] = (tm->tm_min % 10); - regs[MM58274_MINUTE10] = (tm->tm_min / 10); - regs[MM58274_HOUR1] = (tm->tm_hour % 10); - regs[MM58274_HOUR10] = (tm->tm_hour / 10); + regs[MM58274_SECOND1] = (tm->tm_sec % 10); + regs[MM58274_SECOND10] = (tm->tm_sec / 10); + regs[MM58274_MINUTE1] = (tm->tm_min % 10); + regs[MM58274_MINUTE10] = (tm->tm_min / 10); + regs[MM58274_HOUR1] = (tm->tm_hour % 10); + regs[MM58274_HOUR10] = (tm->tm_hour / 10); /* Store hour in 24-hour or 12-hour mode */ if (regs[MM58274_SETTINGS] & 0x01) { regs[MM58274_HOUR1] = (tm->tm_hour % 10); @@ -351,35 +352,35 @@ mm58274_time_set(uint8_t *regs, struct tm *tm) else regs[MM58274_SETTINGS] &= 0x0B; } - regs[MM58274_WEEKDAY] = (tm->tm_wday + 1); - regs[MM58274_DAY1] = (tm->tm_mday % 10); - regs[MM58274_DAY10] = (tm->tm_mday / 10); - regs[MM58274_MONTH1] = ((tm->tm_mon + 1) % 10); - regs[MM58274_MONTH10] = ((tm->tm_mon + 1) / 10); + regs[MM58274_WEEKDAY] = (tm->tm_wday + 1); + regs[MM58274_DAY1] = (tm->tm_mday % 10); + regs[MM58274_DAY10] = (tm->tm_mday / 10); + regs[MM58274_MONTH1] = ((tm->tm_mon + 1) % 10); + regs[MM58274_MONTH10] = ((tm->tm_mon + 1) / 10); /* MM58274 can store 00 to 99 years but M240 uses the YEAR1 register to count 8 years from leap year */ - regs[MM58274_YEAR1] = ((tm->tm_year + 1900) % 8); + regs[MM58274_YEAR1] = ((tm->tm_year + 1900) % 8); /* Keep bit 0 and 1 12-hour / 24-hour and AM / PM */ - regs[MM58274_SETTINGS] &= 0x03; + regs[MM58274_SETTINGS] &= 0x03; /* Set leap counter bits 2 and 3 */ - regs[MM58274_SETTINGS] += (4* (regs[MM58274_YEAR1] & 0x03)); + regs[MM58274_SETTINGS] += (4 * (regs[MM58274_YEAR1] & 0x03)); } /* Get the chip time. */ static void mm58274_time_get(uint8_t *regs, struct tm *tm) { - tm->tm_sec = nibbles(MM58274_SECOND); - tm->tm_min = nibbles(MM58274_MINUTE); + tm->tm_sec = nibbles(MM58274_SECOND); + tm->tm_min = nibbles(MM58274_MINUTE); /* Read hour in 24-hour or 12-hour mode */ if (regs[MM58274_SETTINGS] & 0x01) tm->tm_hour = nibbles(MM58274_HOUR); else tm->tm_hour = ((nibbles(MM58274_HOUR) % 12) + (regs[MM58274_SETTINGS] & 0x04) ? 12 : 0); - tm->tm_wday = (regs[MM58274_WEEKDAY] - 1); - tm->tm_mday = nibbles(MM58274_DAY); - tm->tm_mon = (nibbles(MM58274_MONTH) - 1); + tm->tm_wday = (regs[MM58274_WEEKDAY] - 1); + tm->tm_mday = nibbles(MM58274_DAY); + tm->tm_mon = (nibbles(MM58274_MONTH) - 1); /* MM58274 can store 00 to 99 years but M240 uses the YEAR1 register to count 8 years from leap year */ - tm->tm_year = (1984 + regs[MM58274_YEAR1] - 1900); + tm->tm_year = (1984 + regs[MM58274_YEAR1] - 1900); } /* This is called every second through the NVR/RTC hook. */ @@ -412,14 +413,14 @@ mm58274_start(nvr_t *nvr) static void mm58274_write(uint16_t addr, uint8_t val, void *priv) { - nvr_t *nvr = (nvr_t *) priv; + nvr_t *nvr = (nvr_t *) priv; addr &= 0x0f; val &= 0x0f; /* Update non-read-only changed values if not synchronizing time to host */ if ((addr != MM58274_TENTHS)) - if ((nvr->regs[addr] != val) && !(time_sync & TIME_SYNC_ENABLED)) + if ((nvr->regs[addr] != val) && !(time_sync & TIME_SYNC_ENABLED)) nvr_dosave = 1; if ((addr == MM58274_CONTROL) && (val & 0x04)) { @@ -438,7 +439,7 @@ mm58274_write(uint16_t addr, uint8_t val, void *priv) static uint8_t mm58274_read(uint16_t addr, void *priv) { - nvr_t *nvr = (nvr_t *) priv; + nvr_t *nvr = (nvr_t *) priv; addr &= 0x0f; @@ -489,16 +490,12 @@ m24_kbd_poll(void *priv) if (m24_kbd->wantirq) { m24_kbd->wantirq = 0; picint(2); -#if ENABLE_KEYBOARD_LOG - m24_log("M24: take IRQ\n"); -#endif + xt_olivetti_log("M24: take IRQ\n"); } if (!(m24_kbd->status & STAT_OFULL) && key_queue_start != key_queue_end) { -#if ENABLE_KEYBOARD_LOG - m24_log("Reading %02X from the key queue at %i\n", - m24_kbd->out, key_queue_start); -#endif + xt_olivetti_log("Reading %02X from the key queue at %i\n", + m24_kbd->out, key_queue_start); m24_kbd->out = key_queue[key_queue_start]; key_queue_start = (key_queue_start + 1) & 0xf; m24_kbd->status |= STAT_OFULL; @@ -520,21 +517,32 @@ m24_kbd_adddata_ex(uint16_t val) kbd_adddata_process(val, m24_kbd_adddata); } +/* + From the Olivetti M21/M24 Theory of Operation: + + Port Function + ---- -------- + 60h Keyboard 8041 Data Transfer Read/Write + 61h Control Port A Read/Write + 62h Control Port B Read + 63h Not Used + 64h Keyboard 8041 Command/Status + 65h Communications Port Read + 66h System Configuration Read + 67h System Configuration Read + */ static void m24_kbd_write(uint16_t port, uint8_t val, void *priv) { m24_kbd_t *m24_kbd = (m24_kbd_t *) priv; + uint8_t ret; -#if ENABLE_KEYBOARD_LOG - m24_log("M24: write %04X %02X\n", port, val); -#endif + xt_olivetti_log("M24: write %04X %02X\n", port, val); -#if 0 - if (ram[8] == 0xc3) - output = 3; -#endif switch (port) { case 0x60: + m24_kbd->status &= ~STAT_CD; + if (m24_kbd->param != m24_kbd->param_total) { m24_kbd->params[m24_kbd->param++] = val; if (m24_kbd->param == m24_kbd->param_total) { @@ -558,17 +566,38 @@ m24_kbd_write(uint16_t port, uint8_t val, void *priv) break; default: - m24_log("M24: bad keyboard command complete %02X\n", m24_kbd->command); + xt_olivetti_log("M24: bad keyboard command complete %02X\n", m24_kbd->command); } } } else { m24_kbd->command = val; switch (val) { + /* 01: FD, 05: ANY ---> Customer test reports no keyboard. + 01: AA, 05: 01 ---> Customer test reports 102 Deluxe keyboard. + 01: AA, 05: 02 ---> Customer test reports 83-key keyboard. + 01: AA, 05: 10 ---> Customer test reports M240 keyboard. + 01: AA, 05: 20 ---> Customer test reports 101/102/key keyboard. + 01: AA, 05: 40 or anything else ---> Customer test reports 101/102/key keyboard. + + AA is the correct return for command 01, as confirmed by the M24 Customer Test. */ case 0x01: /*Self-test*/ + m24_kbd_adddata(0xaa); + break; + + case 0x02: /*Olivetti M240: Read SWB*/ + /* SWB on mainboard (off=1) + * bit 7 - use BIOS HD on mainboard (on) / on controller (off) + * bit 6 - use OCG/CGA display adapter (on) / other display adapter (off) + */ + ret = (hdc_current == HDC_INTERNAL) ? 0x00 : 0x80; + ret |= video_is_cga() ? 0x40 : 0x00; + + m24_kbd_adddata(ret); break; case 0x05: /*Read ID*/ - m24_kbd_adddata(0x00); + ret = m24_kbd->id; + m24_kbd_adddata(ret); break; case 0x11: @@ -581,8 +610,11 @@ m24_kbd_write(uint16_t port, uint8_t val, void *priv) m24_kbd->param_total = 4; break; + case 0x13: /*Sent by Olivetti M240 Customer Diagnostics*/ + break; + default: - m24_log("M24: bad keyboard command %02X\n", val); + xt_olivetti_log("M24: bad keyboard command %02X\n", val); } } break; @@ -597,9 +629,17 @@ m24_kbd_write(uint16_t port, uint8_t val, void *priv) was_speaker_enable = 1; pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1); break; + + case 0x64: + m24_kbd->status |= STAT_CD; + + if (val == 0x02) + m24_kbd_adddata(0x00); } } +extern uint8_t random_generate(void); + static uint8_t m24_kbd_read(uint16_t port, void *priv) { @@ -622,16 +662,22 @@ m24_kbd_read(uint16_t port, void *priv) break; case 0x61: + /* MS-DOS 5.00 and higher's KEYB.COM freezes due to port 61h not having the + AT refresh toggle, because for some reson it thinks the M24 is an AT. + + A German-language site confirms this also happens on real hardware. + + The M240 is not affected. */ ret = ppi.pb; break; case 0x64: - ret = m24_kbd->status; + ret = m24_kbd->status & 0x0f; m24_kbd->status &= ~(STAT_RTIMEOUT | STAT_TTIMEOUT); break; default: - m24_log("\nBad M24 keyboard read %04X\n", port); + xt_olivetti_log("\nBad M24 keyboard read %04X\n", port); } return (ret); @@ -771,6 +817,561 @@ ms_poll(int x, int y, int z, int b, void *priv) return (0); } +/* Remapping as follows: + + - Left Windows (E0 5B) -> NUMPAD 00 (54); + - Print Screen (E0 37) -> SCR PRT (55); + - Menu (E0 5D) -> HELP (56); + - NumPad Enter (E0 1C) -> NUMPAD ENTER (57). + - Left (E0 4B) -> LEFT (58); + - Down (E0 50) -> DOWN (59); + - Right (E0 4D) -> RIGHT (5A); + - Up (E0 48) -> UP (5B); + - Page Up (E0 49) -> CLEAR (5C); + - Page Down (E0 51) -> BREAK (5D); + - CE Key (56) -> CE KEY (5E); + WARNING: The Olivetti CE Key is undocumented, but can be inferred from the fact + its position is missing in the shown layout, it being used by the Italian + keyboard layout, the keyboard is called 103-key, but only 102 keys are + shown. + - NumPad / (E0 35) -> NUMPAD / (5F); + - F11 (57) -> F11 (60); + - F12 (58) -> F12 (61); + - Insert (E0 52) -> F13 (62); + - Home (E0 47) -> F14 (63); + - Delete (E0 53) -> F15 (64); + - End (E0 4F) -> F16 (65); + - Right Alt (Gr)(E0 38) -> F16 (66); + - Right Windows (E0 5C) -> F18 (67). + */ +const scancode scancode_olivetti_m24_deluxe[512] = { + // clang-format off + { {0}, {0} }, { {0x01, 0}, {0x81, 0} }, + { {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} }, + { {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} }, + { {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} }, + { {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} }, + { {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} }, + { {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} }, + { {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} }, + { {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} }, + { {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} }, + { {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} }, + { {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} }, + { {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} }, + { {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} }, + { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, + { {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} }, + { {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} }, + { {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} }, + { {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} }, + { {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} }, + { {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} }, + { {0x2a, 0}, {0xaa, 0} }, { {0x2b, 0}, {0xab, 0} }, + { {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} }, + { {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} }, + { {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} }, + { {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} }, + { {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} }, + { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, + { {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} }, + { {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} }, + { {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} }, + { {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} }, + { {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} }, + { {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} }, + { {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} }, + { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, + { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, + { {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} }, + { {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} }, + { {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} }, + { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, + { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, + { {0}, {0} }, { {0}, {0} }, + { {0x5e, 0}, {0xde, 0} }, { {0x60, 0}, {0xe0, 0} }, /*054*/ + { {0x61, 0}, {0xe1, 0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*058*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*05c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*060*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*064*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*068*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*06c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*070*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*074*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*078*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*07c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*080*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*084*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*088*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*08c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*090*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*094*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*098*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*09c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0a0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0a4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0a8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0ac*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0b0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0b4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0b8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0bc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0c0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0c4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0c8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0cc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0d0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0d4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0d8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0dc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0e0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0e4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0e8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0ec*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0f0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0f4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0f8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0fc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*100*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*104*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*108*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*10c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*110*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*114*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*118*/ + { {0x57, 0}, {0xd7, 0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*11c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*120*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*124*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*128*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*12c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*130*/ + { {0}, {0} }, { {0x5f, 0}, {0xdf, 0} }, + { {0}, {0} }, { {0x37, 0}, {0xb7, 0} }, /*134*/ + { {0x66, 0}, {0xe6, 0} }, { {0x55, 0}, {0xd5, 0} }, + { {0}, {0} }, { {0}, {0} }, /*138*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*13c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*140*/ + { {0}, {0} }, { {0}, {0} }, + { {0x46, 0}, {0xc6, 0} }, { {0x63, 0}, {0xe3, 0} }, /*144*/ + { {0x5b, 0}, {0xdb, 0} }, { {0x5c, 0}, {0xdc, 0} }, + { {0}, {0} }, { {0x58, 0}, {0xd8, 0} }, /*148*/ + { {0}, {0} }, { {0x5a, 0}, {0xda, 0} }, + { {0}, {0} }, { {0x65, 0}, {0xe5, 0} }, /*14c*/ + { {0x59, 0}, {0xd9, 0} }, { {0x5d, 0}, {0xdd, 0} }, + { {0x62, 0}, {0xe2, 0} }, { {0x64, 0}, {0xe4, 0} }, /*150*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*154*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0x54, 0}, {0xd4, 0} }, /*158*/ + { {0x67, 0}, {0xe7, 0} }, { {0x56, 0}, {0xd6, 0} }, + { {0}, {0} }, { {0}, {0} }, /*15c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*160*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*164*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*168*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*16c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*170*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*174*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*148*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*17c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*180*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*184*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*88*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*18c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*190*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*194*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*198*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*19c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1a0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1a4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1a8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1ac*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1b0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1b4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1b8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1bc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1c0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1c4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1c8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1cc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1d0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1d4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1d8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1dc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1e0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1e4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1e8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1ec*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1f0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1f4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1f8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} } /*1fc*/ + // clang-format on +}; + +/* Remapping as follows: + + - Left Windows (E0 5B) -> 54; + - Right Windows (E0 5C) -> 56; + - Menu (E0 5D) -> 5C. + */ +const scancode scancode_olivetti_m240[512] = { + // clang-format off + { {0}, {0} }, { {0x01, 0}, {0x81, 0} }, + { {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} }, + { {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} }, + { {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} }, + { {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} }, + { {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} }, + { {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} }, + { {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} }, + { {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} }, + { {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} }, + { {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} }, + { {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} }, + { {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} }, + { {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} }, + { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, + { {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} }, + { {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} }, + { {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} }, + { {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} }, + { {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} }, + { {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} }, + { {0x2a, 0}, {0xaa, 0} }, { {0x2b, 0}, {0xab, 0} }, + { {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} }, + { {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} }, + { {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} }, + { {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} }, + { {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} }, + { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, + { {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} }, + { {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} }, + { {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} }, + { {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} }, + { {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} }, + { {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} }, + { {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} }, + { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, + { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, + { {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} }, + { {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} }, + { {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} }, + { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, + { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*054*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*058*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*05c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*060*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*064*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*068*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*06c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*070*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*074*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*078*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*07c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*080*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*084*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*088*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*08c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*090*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*094*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*098*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*09c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0a0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0a4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0a8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0ac*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0b0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0b4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0b8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0bc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0c0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0c4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0c8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0cc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0d0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0d4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0d8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0dc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0e0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0e4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0e8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0ec*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0f0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0f4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0f8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*0fc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*100*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*104*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*108*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*10c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*110*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*114*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*118*/ + { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, + { {0}, {0} }, { {0}, {0} }, /*11c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*120*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*124*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*128*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*12c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*130*/ + { {0}, {0} }, { {0x35, 0}, {0xb5, 0} }, + { {0}, {0} }, { {0x37, 0}, {0xb7, 0} }, /*134*/ + { {0x38, 0}, {0xb8, 0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*138*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*13c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*140*/ + { {0}, {0} }, { {0}, {0} }, + { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, /*144*/ + { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, + { {0}, {0} }, { {0x4b, 0}, {0xcb, 0} }, /*148*/ + { {0}, {0} }, { {0x4d, 0}, {0xcd, 0} }, + { {0}, {0} }, { {0x4f, 0}, {0xcf, 0} }, /*14c*/ + { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, + { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, /*150*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*154*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*158*/ + { {0}, {0} }, { {0x54, 0}, {0xd4, 0} }, + { {0x56, 0}, {0xd6, 0} }, { {0x5c, 0}, {0xdc, 0} }, /*15c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*160*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*164*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*168*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*16c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*170*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*174*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*148*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*17c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*180*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*184*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*88*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*18c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*190*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*194*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*198*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*19c*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1a0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1a4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1a8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1ac*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1b0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1b4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1b8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1bc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1c0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1c4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1c8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1cc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1d0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1d4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1d8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1dc*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1e0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1e4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1e8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1ec*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1f0*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1f4*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} }, /*1f8*/ + { {0}, {0} }, { {0}, {0} }, + { {0}, {0} }, { {0}, {0} } /*1fc*/ + // clang-format on +}; + static void m24_kbd_init(m24_kbd_t *kbd) { @@ -784,12 +1385,14 @@ m24_kbd_init(m24_kbd_t *kbd) m24_kbd_reset(kbd); timer_add(&kbd->send_delay_timer, m24_kbd_poll, kbd, 1); - /* Tell mouse driver about our internal mouse. */ - mouse_reset(); - mouse_set_buttons(2); - mouse_set_poll(ms_poll, kbd); + if (mouse_type == MOUSE_TYPE_INTERNAL) { + /* Tell mouse driver about our internal mouse. */ + mouse_reset(); + mouse_set_buttons(2); + mouse_set_poll(ms_poll, kbd); + } - keyboard_set_table(scancode_xt); + keyboard_set_table((kbd->id == 0x01) ? scancode_olivetti_m24_deluxe : scancode_olivetti_m240); keyboard_set_is_amstrad(0); } @@ -1005,6 +1608,16 @@ m24_read(uint16_t port, void *priv) int i, fdd_count = 0; switch (port) { + case 0x62: + /* Control Port B Read */ + ret = 0xff; + break; + + case 0x65: + /* Communications Port Read */ + ret = 0xff; + break; + /* * port 66: * DIPSW-0 on mainboard (off=present=1) @@ -1043,6 +1656,7 @@ m24_read(uint16_t port, void *priv) break; } break; + /* * port 67: * DIPSW-1 on mainboard (off=present=1) @@ -1079,18 +1693,82 @@ m24_read(uint16_t port, void *priv) else ret |= 0x0; + /* Switch 4 - The M21/M24 Theory of Operation says + "Reserved for HDU", same as for Switch 3 */ + /* Switch 3 - Disable internal BIOS HD */ - ret |= 0x4; + if (hdc_current != HDC_INTERNAL) + ret |= 0x4; /* Switch 2 - Set fast startup */ ret |= 0x2; - + + /* 1 = 720 kB (3.5"), 0 = 360 kB (5.25") */ + ret |= (fdd_doublestep_40(0) || fdd_doublestep_40(1)) ? 0x1 : 0x0; break; } return (ret); } +static uint8_t +m240_read(uint16_t port, void *priv) +{ + uint8_t ret = 0x00; + int i, fdd_count = 0; + + switch (port) { + case 0x62: + /* SWA on Olivetti M240 mainboard (off=1) */ + ret = 0x00; + if (ppi.pb & 0x8) { + /* Switches 4, 5 - floppy drives (number) */ + for (i = 0; i < FDD_NUM; i++) { + if (fdd_get_flags(i)) + fdd_count++; + } + if (!fdd_count) + ret |= 0x00; + else + ret |= ((fdd_count - 1) << 2); + /* Switches 6, 7 - monitor type */ + if (video_is_mda()) + ret |= 0x3; + else if (video_is_cga()) + ret |= 0x2; /* 0x10 would be 40x25 */ + else + ret |= 0x0; + } else { + /* bit 2 always on */ + ret |= 0x4; + /* Switch 8 - 8087 FPU. */ + if (hasfpu) + ret |= 0x02; + } + break; + + case 0x63: + /* Olivetti M240 SWB: + - Bit 7: 1 = MFDD (= high-density) unit present (Customer Test will then always think Drive 2 is absent), + 0 = MFD unit absent; + - Bit 6: 1 = Second drive is 3.5" (for low density drive, this means 80-track), + 0 = Second drive is 5.25" (for low density drive, this means 40-track). + - Bit 5: 1 = First drive is 3.5" (for low density drive, this means 80-track), + 0 = First drive is 5.25" (for low density drive, this means 40-track). + */ + + ret = (fdd_is_hd(0) || fdd_is_hd(1)) ? 0x80 : 0x00; + ret |= fdd_doublestep_40(1) ? 0x40 : 0x00; + ret |= fdd_doublestep_40(0) ? 0x20 : 0x00; + break; + } + + return (ret); +} + +/* + * Uses M21/M24/M240 keyboard controller and M24 102/103-key Deluxe keyboard. + */ int machine_xt_m24_init(const machine_t *model) { @@ -1115,7 +1793,7 @@ machine_xt_m24_init(const machine_t *model) device_add(&fdc_xt_device); /* Address 66-67 = mainboard dip-switch settings */ - io_sethandler(0x0066, 2, m24_read, NULL, NULL, NULL, NULL, NULL, NULL); + io_sethandler(0x0065, 3, m24_read, NULL, NULL, NULL, NULL, NULL, NULL); standalone_gameport_type = &gameport_device; @@ -1134,22 +1812,29 @@ machine_xt_m24_init(const machine_t *model) if (gfxcard == VID_INTERNAL) device_add(&ogc_m24_device); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); + + io_sethandler(0x0062, 1, m24_read, NULL, NULL, NULL, NULL, NULL, NULL); + + m24_kbd->id = 0x01; + m24_kbd_init(m24_kbd); device_add_ex(&m24_kbd_device, m24_kbd); - device_add(&st506_xt_wd1002a_wx1_nobios_device); + if (hdc_current == HDC_INTERNAL) + device_add(&st506_xt_wd1002a_wx1_nobios_device); return ret; } /* - * Current bugs: - * - handles only 360kb floppy drives (drive type and capacity selectable with jumpers mapped to unknown memory locations) + * Uses M21/M24/M240 keyboard controller and M240 keyboard. */ int machine_xt_m240_init(const machine_t *model) { - int ret; + int ret; + m24_kbd_t *m24_kbd; nvr_t *nvr; ret = bios_load_interleaved("roms/machines/m240/olivetti_m240_pch6_2.04_low.bin", @@ -1159,12 +1844,15 @@ machine_xt_m240_init(const machine_t *model) if (bios_only || !ret) return ret; + m24_kbd = (m24_kbd_t *) malloc(sizeof(m24_kbd_t)); + memset(m24_kbd, 0x00, sizeof(m24_kbd_t)); + machine_common_init(model); pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); /* Address 66-67 = mainboard dip-switch settings */ - io_sethandler(0x0066, 2, m24_read, NULL, NULL, NULL, NULL, NULL, NULL); + io_sethandler(0x0062, 2, m240_read, NULL, NULL, NULL, NULL, NULL, NULL); /* * port 60: should return jumper settings only under unknown conditions @@ -1172,11 +1860,13 @@ machine_xt_m240_init(const machine_t *model) * bit 7 - use BIOS HD on mainboard (on) / on controller (off) * bit 6 - use OCG/CGA display adapter (on) / other display adapter (off) */ - device_add(&keyboard_at_olivetti_device); - device_add(&port_6x_olivetti_device); + m24_kbd->id = 0x10; + + m24_kbd_init(m24_kbd); + device_add_ex(&m24_kbd_device, m24_kbd); if (fdc_type == FDC_INTERNAL) - device_add(&fdc_xt_device); + device_add(&fdc_at_device); /* io.c logs clearly show it using port 3F7 */ if (joystick_type) device_add(&gameport_device); @@ -1191,6 +1881,9 @@ machine_xt_m240_init(const machine_t *model) mm58274_init(nvr, model->nvrmask + 1); + if (hdc_current == HDC_INTERNAL) + device_add(&st506_xt_wd1002a_wx1_nobios_device); + return ret; } diff --git a/src/machine/m_xt_philips.c b/src/machine/m_xt_philips.c index 2c5bbb53d..bc1b6f792 100644 --- a/src/machine/m_xt_philips.c +++ b/src/machine/m_xt_philips.c @@ -1,20 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the Philips XT-compatible machines. + * Emulation of the Philips XT-compatible machines. * * * - * Authors: EngiNerd + * Authors: EngiNerd * - * Copyright 2020-2021 EngiNerd. + * Copyright 2020-2021 EngiNerd. */ - #include #include #include diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 51d23da40..f61ce639b 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -57,9 +57,9 @@ * Miran Grca, * Sarah Walker, * - * Copyright 2018,2019 Fred N. van Kempen. - * Copyright 2018,2019 Miran Grca. - * Copyright 2018,2019 Sarah Walker. + * Copyright 2018-2019 Fred N. van Kempen. + * Copyright 2018-2019 Miran Grca. + * Copyright 2018-2019 Sarah Walker. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/machine/m_xt_t1000_vid.c b/src/machine/m_xt_t1000_vid.c index cdd20cae1..60fb59082 100644 --- a/src/machine/m_xt_t1000_vid.c +++ b/src/machine/m_xt_t1000_vid.c @@ -15,9 +15,9 @@ * Miran Grca, * Sarah Walker, * - * Copyright 2018,2019 Fred N. van Kempen. - * Copyright 2018,2019 Miran Grca. - * Copyright 2018,2019 Sarah Walker. + * Copyright 2018-2019 Fred N. van Kempen. + * Copyright 2018-2019 Miran Grca. + * Copyright 2018-2019 Sarah Walker. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -94,7 +94,7 @@ t1000_display_set(uint8_t internal) } uint8_t -t1000_display_get() +t1000_display_get(void) { return (uint8_t) st_display_internal; } @@ -723,7 +723,7 @@ static const device_config_t t1000_config[] = { .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t t1000_video_device = { diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index 6d64fe438..5bf958d8a 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -37,7 +37,7 @@ typedef struct xi8088_t { static xi8088_t xi8088; uint8_t -xi8088_turbo_get() +xi8088_turbo_get(void) { return xi8088.turbo; } @@ -156,7 +156,7 @@ static const device_config_t xi8088_config[] = { .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t xi8088_device = { diff --git a/src/machine/machine.c b/src/machine/machine.c index c2347b107..6b496b06a 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handling of the emulated machines. + * Handling of the emulated machines. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #include #include diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index baa0d9cea..0b846e784 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2101,7 +2101,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PC, - .flags = MACHINE_FLAGS_NONE, + .flags = MACHINE_MFM, .ram = { .min = 128, .max = 640, @@ -11969,8 +11969,8 @@ const machine_t machines[] = { /* Saved copies - jumpers get applied to these. We use also machine_gpio to store IBM PC/XT jumpers as they need more than one byte. */ -static uint16_t machine_p1; -static uint32_t machine_gpio; +static uint16_t machine_p1; +static uint32_t machine_gpio; uint8_t machine_get_p1(void) @@ -12005,97 +12005,97 @@ machine_set_gpio(uint32_t gpio) int machine_count(void) { - return((sizeof(machines) / sizeof(machine_t)) - 1); + return ((sizeof(machines) / sizeof(machine_t)) - 1); } char * machine_getname(void) { - return((char *)machines[machine].name); + return ((char *) machines[machine].name); } char * machine_getname_ex(int m) { - return((char *)machines[m].name); + return ((char *) machines[m].name); } const device_t * machine_getdevice(int m) { if (machines[m].device) - return(machines[m].device); + return (machines[m].device); - return(NULL); + return (NULL); } const device_t * machine_getviddevice(int m) { if (machines[m].vid_device) - return(machines[m].vid_device); + return (machines[m].vid_device); - return(NULL); + return (NULL); } const device_t * machine_getsnddevice(int m) { if (machines[m].snd_device) - return(machines[m].snd_device); + return (machines[m].snd_device); - return(NULL); + return (NULL); } const device_t * machine_getnetdevice(int m) { if (machines[m].net_device) - return(machines[m].net_device); + return (machines[m].net_device); - return(NULL); + return (NULL); } char * machine_get_internal_name(void) { - return((char *)machines[machine].internal_name); + return ((char *) machines[machine].internal_name); } char * machine_get_internal_name_ex(int m) { - return((char *)machines[m].internal_name); + return ((char *) machines[m].internal_name); } int machine_get_nvrmask(int m) { - return(machines[m].nvrmask); + return (machines[m].nvrmask); } int machine_has_flags(int m, int flags) { - return(machines[m].flags & flags); + return (machines[m].flags & flags); } int machine_has_bus(int m, int bus_flags) { - return(machines[m].bus_flags & bus_flags); + return (machines[m].bus_flags & bus_flags); } int machine_has_cartridge(int m) { - return(machine_has_bus(m, MACHINE_CARTRIDGE) ? 1 : 0); + return (machine_has_bus(m, MACHINE_CARTRIDGE) ? 1 : 0); } int machine_get_min_ram(int m) { - return(machines[m].ram.min); + return (machines[m].ram.min); } int @@ -12111,13 +12111,13 @@ machine_get_max_ram(int m) int machine_get_ram_granularity(int m) { - return(machines[m].ram.step); + return (machines[m].ram.step); } int machine_get_type(int m) { - return(machines[m].type); + return (machines[m].type); } int @@ -12126,16 +12126,22 @@ machine_get_machine_from_internal_name(char *s) int c = 0; while (machines[c].init != NULL) { - if (!strcmp(machines[c].internal_name, (const char *)s)) - return(c); + if (!strcmp(machines[c].internal_name, (const char *) s)) + return (c); c++; } - return(0); + return (0); } int machine_has_mouse(void) { - return(machines[machine].flags & MACHINE_MOUSE); + return (machines[machine].flags & MACHINE_MOUSE); +} + +int +machine_is_sony(void) +{ + return (!strcmp(machines[machine].internal_name, "pcv90")); } diff --git a/src/machine_status.c b/src/machine_status.c index 47541d3ef..65f4704b4 100644 --- a/src/machine_status.c +++ b/src/machine_status.c @@ -26,7 +26,7 @@ machine_status_t machine_status; void -machine_status_init() +machine_status_init(void) { for (size_t i = 0; i < FDD_NUM; ++i) { machine_status.fdd[i].empty = (strlen(floppyfns[i]) == 0); diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index 9eae342fd..1739d4807 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(mem OBJECT catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c rom.c diff --git a/src/mem/catalyst_flash.c b/src/mem/catalyst_flash.c index b49c0671c..043a24b37 100644 --- a/src/mem/catalyst_flash.c +++ b/src/mem/catalyst_flash.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Intel 1 Mbit and 2 Mbit, 8-bit and - * 16-bit flash devices. + * Implementation of the Intel 1 Mbit and 2 Mbit, 8-bit and + * 16-bit flash devices. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include diff --git a/src/mem/i2c_eeprom.c b/src/mem/i2c_eeprom.c index 9a2e2876e..22b7154d6 100644 --- a/src/mem/i2c_eeprom.c +++ b/src/mem/i2c_eeprom.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of the 24Cxx series of I2C EEPROMs. + * Emulation of the 24Cxx series of I2C EEPROMs. * * * - * Authors: RichardG, + * Authors: RichardG, * - * Copyright 2020 RichardG. + * Copyright 2020 RichardG. */ #include #include diff --git a/src/mem/intel_flash.c b/src/mem/intel_flash.c index bd24f5bcc..18b8a4b3d 100644 --- a/src/mem/intel_flash.c +++ b/src/mem/intel_flash.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Intel 1 Mbit and 2 Mbit, 8-bit and - * 16-bit flash devices. + * Implementation of the Intel 1 Mbit and 2 Mbit, 8-bit and + * 16-bit flash devices. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include diff --git a/src/mem/mem.c b/src/mem/mem.c index e0456bf5c..4d5a5238b 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -55,12 +55,12 @@ #endif mem_mapping_t ram_low_mapping, /* 0..640K mapping */ - ram_mid_mapping, /* 640..1024K mapping */ - ram_mid_mapping2, /* 640..1024K mapping, second part, for SiS 471 in relocate mode */ - ram_remapped_mapping, /* 640..1024K mapping */ - ram_remapped_mapping2,/* 640..1024K second mapping, for SiS 471 mode */ - ram_high_mapping, /* 1024K+ mapping */ - ram_2gb_mapping, /* 1024M+ mapping */ + ram_mid_mapping, /* 640..1024K mapping */ + ram_mid_mapping2, /* 640..1024K mapping, second part, for SiS 471 in relocate mode */ + ram_remapped_mapping, /* 640..1024K mapping */ + ram_remapped_mapping2, /* 640..1024K second mapping, for SiS 471 mode */ + ram_high_mapping, /* 1024K+ mapping */ + ram_2gb_mapping, /* 1024M+ mapping */ ram_split_mapping, bios_mapping, bios_high_mapping; @@ -2806,9 +2806,9 @@ mem_remap_top(int kb) uint32_t c; uint32_t start = (mem_size >= 1024) ? mem_size : 1024; int offset, size = mem_size - 640; - int set = 1; - static int old_kb = 0; - int sis_mode = 0; + int set = 1; + static int old_kb = 0; + int sis_mode = 0; uint32_t start_addr = 0, addr = 0; mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); @@ -2817,7 +2817,7 @@ mem_remap_top(int kb) /* SiS 471 special mode. */ if (kb == -256) { - kb = 256; + kb = 256; sis_mode = 1; } @@ -2830,11 +2830,11 @@ mem_remap_top(int kb) if (size > kb) size = kb; - remap_start_addr = start << 10; + remap_start_addr = start << 10; remap_start_addr2 = (start << 10) + 0x00020000; for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { - offset = c - ((start * 1024) >> 12); + offset = c - ((start * 1024) >> 12); /* Use A0000-BFFFF, D0000-EFFFF instead of C0000-DFFFF, E0000-FFFFF. */ addr = 0xa0000 + (offset << 12); if (sis_mode) { @@ -2858,8 +2858,8 @@ mem_remap_top(int kb) mem_set_mem_state_both(start * 1024, size * 1024, set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); for (c = 0xa0; c < 0xf0; c++) { - if ((c >= 0xc0) && (c <= 0xcf)) - continue; + if ((c >= 0xc0) && (c <= 0xcf)) + continue; if (sis_mode || ((c << 12) >= (mem_size << 10))) pages[c].mem = page_ff; diff --git a/src/mem/rom.c b/src/mem/rom.c index a1dbc55a1..6c964f2c3 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -1,26 +1,26 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handling of ROM image files. + * Handling of ROM image files. * - * NOTES: - pc2386 BIOS is corrupt (JMP at F000:FFF0 points to RAM) - * - pc2386 video BIOS is underdumped (16k instead of 24k) - * - c386sx16 BIOS fails checksum + * NOTES: - pc2386 BIOS is corrupt (JMP at F000:FFF0 points to RAM) + * - pc2386 video BIOS is underdumped (16k instead of 24k) + * - c386sx16 BIOS fails checksum * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018-2019 Fred N. van Kempen. */ #include #include @@ -87,7 +87,7 @@ rom_add_path(const char *path) } FILE * -rom_fopen(char *fn, char *mode) +rom_fopen(const char *fn, char *mode) { char temp[1024]; rom_path_t *rom_path; @@ -205,7 +205,7 @@ rom_readl(uint32_t addr, void *priv) } int -rom_load_linear_oddeven(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) +rom_load_linear_oddeven(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) { FILE *f = rom_fopen(fn, "rb"); int i; @@ -241,7 +241,7 @@ rom_load_linear_oddeven(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) /* Load a ROM BIOS from its chips, interleaved mode. */ int -rom_load_linear(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) +rom_load_linear(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) { FILE *f = rom_fopen(fn, "rb"); @@ -270,7 +270,7 @@ rom_load_linear(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) /* Load a ROM BIOS from its chips, linear mode with high bit flipped. */ int -rom_load_linear_inverted(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) +rom_load_linear_inverted(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) { FILE *f = rom_fopen(fn, "rb"); @@ -308,7 +308,7 @@ rom_load_linear_inverted(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) /* Load a ROM BIOS from its chips, interleaved mode. */ int -rom_load_interleaved(char *fnl, char *fnh, uint32_t addr, int sz, int off, uint8_t *ptr) +rom_load_interleaved(const char *fnl, const char *fnh, uint32_t addr, int sz, int off, uint8_t *ptr) { FILE *fl = rom_fopen(fnl, "rb"); FILE *fh = rom_fopen(fnh, "rb"); @@ -478,7 +478,7 @@ bios_add(void) /* These four are for loading the BIOS. */ int -bios_load(char *fn1, char *fn2, uint32_t addr, int sz, int off, int flags) +bios_load(const char *fn1, const char *fn2, uint32_t addr, int sz, int off, int flags) { uint8_t ret = 0; uint8_t *ptr = NULL; @@ -525,7 +525,7 @@ bios_load(char *fn1, char *fn2, uint32_t addr, int sz, int off, int flags) } int -bios_load_linear_combined(char *fn1, char *fn2, int sz, int off) +bios_load_linear_combined(const char *fn1, const char *fn2, int sz, int off) { uint8_t ret = 0; @@ -536,7 +536,7 @@ bios_load_linear_combined(char *fn1, char *fn2, int sz, int off) } int -bios_load_linear_combined2(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5, int sz, int off) +bios_load_linear_combined2(const char *fn1, const char *fn2, const char *fn3, const char *fn4, const char *fn5, int sz, int off) { uint8_t ret = 0; @@ -551,7 +551,7 @@ bios_load_linear_combined2(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5 } int -bios_load_linear_combined2_ex(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5, int sz, int off) +bios_load_linear_combined2_ex(const char *fn1, const char *fn2, const char *fn3, const char *fn4, const char *fn5, int sz, int off) { uint8_t ret = 0; @@ -566,7 +566,7 @@ bios_load_linear_combined2_ex(char *fn1, char *fn2, char *fn3, char *fn4, char * } int -rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags) +rom_init(rom_t *rom, const char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags) { rom_log("rom_init(%08X, %s, %08X, %08X, %08X, %08X, %08X)\n", rom, fn, addr, sz, mask, off, flags); @@ -595,7 +595,7 @@ rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_ } int -rom_init_oddeven(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags) +rom_init_oddeven(rom_t *rom, const char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags) { rom_log("rom_init(%08X, %08X, %08X, %08X, %08X, %08X, %08X)\n", rom, fn, addr, sz, mask, off, flags); @@ -624,7 +624,7 @@ rom_init_oddeven(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, } int -rom_init_interleaved(rom_t *rom, char *fnl, char *fnh, uint32_t addr, int sz, int mask, int off, uint32_t flags) +rom_init_interleaved(rom_t *rom, const char *fnl, const char *fnh, uint32_t addr, int sz, int mask, int off, uint32_t flags) { /* Allocate a buffer for the image. */ rom->rom = malloc(sz); diff --git a/src/mem/smram.c b/src/mem/smram.c index 64f3417aa..6057f0a3c 100644 --- a/src/mem/smram.c +++ b/src/mem/smram.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * SMRAM handling. + * SMRAM handling. * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2020 Miran Grca. */ #include #include diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 50f07612b..98252d49e 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -1,20 +1,20 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # -add_library(net OBJECT network.c net_pcap.c net_slirp.c net_dp8390.c net_3c503.c - net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c) +add_library(net OBJECT network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c + net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c) option(SLIRP_EXTERNAL "Link against the system-provided libslirp library" OFF) mark_as_advanced(SLIRP_EXTERNAL) diff --git a/src/network/net_3c501.c b/src/network/net_3c501.c new file mode 100644 index 000000000..19ad587c2 --- /dev/null +++ b/src/network/net_3c501.c @@ -0,0 +1,1223 @@ +/* + * 86Box An emulator of (mostly) x86-based PC systems and devices, + * using the ISA, EISA, VLB, MCA, and PCI system buses, + * roughly spanning the era between 1981 and 1995. + * + * This file is part of the 86Box Project. + * + * Implementation of the following network controller: + * - 3Com Etherlink 3c500/3c501 (ISA 8-bit). + * + * + * + * Based on @(#)Dev3C501.cpp Oracle (VirtualBox) + * + * Authors: TheCollector1995, + * Oracle + * + * Copyright 2022 TheCollector1995. + * Portions Copyright (C) 2022 Oracle and/or its affilitates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/dma.h> +#include <86box/pic.h> +#include <86box/mem.h> +#include <86box/random.h> +#include <86box/device.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/network.h> +#include <86box/net_3c501.h> +#include <86box/bswap.h> + +/* Maximum number of times we report a link down to the guest (failure to send frame) */ +#define ELNK_MAX_LINKDOWN_REPORTED 3 + +/* Maximum number of times we postpone restoring a link that is temporarily down. */ +#define ELNK_MAX_LINKRST_POSTPONED 3 + +/* Maximum frame size we handle */ +#define MAX_FRAME 1536 + +/* Size of the packet buffer. */ +#define ELNK_BUF_SIZE 2048 + +/* The packet buffer address mask. */ +#define ELNK_BUF_ADR_MASK (ELNK_BUF_SIZE - 1) + +/* The GP buffer pointer address within the buffer. */ +#define ELNK_GP(dev) (dev->uGPBufPtr & ELNK_BUF_ADR_MASK) + +/* The GP buffer pointer mask. + * NB: The GP buffer pointer is internally a 12-bit counter. When addressing into the + * packet buffer, bit 11 is ignored. Required to pass 3C501 diagnostics. + */ +#define ELNK_GP_MASK 0xfff + +/********************************************************************************************************************************* +* Structures and Typedefs * +*********************************************************************************************************************************/ + + +/** + * EtherLink Transmit Command Register. + */ +typedef struct ELNK_XMIT_CMD { + uint8_t det_ufl : 1; /* Detect underflow. */ + uint8_t det_coll : 1; /* Detect collision. */ + uint8_t det_16col : 1; /* Detect collision 16. */ + uint8_t det_succ : 1; /* Detect successful xmit. */ + uint8_t unused : 4; +} EL_XMT_CMD; + +/** + * EtherLink Transmit Status Register. + * + * We will never see any real collisions, although collisions (including 16 + * successive collisions) may be useful to report when the link is down + * (something the 3C501 does not have a concept of). + */ +typedef struct ELNK_XMIT_STAT { + uint8_t uflow : 1; /* Underflow on transmit. */ + uint8_t coll : 1; /* Collision on transmit. */ + uint8_t coll16 : 1; /* 16 collisions on transmit. */ + uint8_t ready : 1; /* Ready for a new frame. */ + uint8_t undef : 4; +} EL_XMT_STAT; + +/** Address match (adr_match) modes. */ +typedef enum { + EL_ADRM_DISABLED = 0, /* Receiver disabled. */ + EL_ADRM_PROMISC = 1, /* Receive all addresses. */ + EL_ADRM_BCAST = 2, /* Receive station + broadcast. */ + EL_ADRM_MCAST = 3 /* Receive station + multicast. */ +} EL_ADDR_MATCH; + +/** + * EtherLink Receive Command Register. + */ +typedef struct ELNK_RECV_CMD { + uint8_t det_ofl : 1; /* Detect overflow errors. */ + uint8_t det_fcs : 1; /* Detect FCS errors. */ + uint8_t det_drbl : 1; /* Detect dribble error. */ + uint8_t det_runt : 1; /* Detect short frames. */ + uint8_t det_eof : 1; /* Detect EOF (frames without overflow). */ + uint8_t acpt_good : 1; /* Accept good frames. */ + uint8_t adr_match : 2; /* Address match mode. */ +} EL_RCV_CMD; + +/** + * EtherLink Receive Status Register. + */ +typedef struct ELNK_RECV_STAT { + uint8_t oflow : 1; /* Overflow on receive. */ + uint8_t fcs : 1; /* FCS error. */ + uint8_t dribble : 1; /* Dribble error. */ + uint8_t runt : 1; /* Short frame. */ + uint8_t no_ovf : 1; /* Received packet w/o overflow. */ + uint8_t good : 1; /* Received good packet. */ + uint8_t undef : 1; + uint8_t stale : 1; /* Stale receive status. */ +} EL_RCV_STAT; + +/** Buffer control (buf_ctl) modes. */ +typedef enum { + EL_BCTL_SYSTEM = 0, /* Host has buffer access. */ + EL_BCTL_XMT_RCV = 1, /* Transmit, then receive. */ + EL_BCTL_RECEIVE = 2, /* Receive. */ + EL_BCTL_LOOPBACK = 3 /* Loopback. */ +} EL_BUFFER_CONTROL; + +/** + * EtherLink Auxiliary Status Register. + */ +typedef struct ELNK_AUX_CMD { + uint8_t ire : 1; /* Interrupt Request Enable. */ + uint8_t xmit_bf : 1; /* Xmit packets with bad FCS. */ + uint8_t buf_ctl : 2; /* Packet buffer control. */ + uint8_t unused : 1; + uint8_t dma_req : 1; /* DMA request. */ + uint8_t ride : 1; /* Request Interrupt and DMA Enable. */ + uint8_t reset : 1; /* Card in reset while set. */ +} EL_AUX_CMD; + +/** + * EtherLink Auxiliary Status Register. + */ +typedef struct ELNK_AUX_STAT { + uint8_t recv_bsy : 1; /* Receive busy. */ + uint8_t xmit_bf : 1; /* Xmit packets with bad FCS. */ + uint8_t buf_ctl : 2; /* Packet buffer control. */ + uint8_t dma_done : 1; /* DMA done. */ + uint8_t dma_req : 1; /* DMA request. */ + uint8_t ride : 1; /* Request Interrupt and DMA Enable. */ + uint8_t xmit_bsy : 1; /* Transmit busy. */ +} EL_AUX_STAT; + +/** + * Internal interrupt status. + */ +typedef struct ELNK_INTR_STAT { + uint8_t recv_intr : 1; /* Receive interrupt status. */ + uint8_t xmit_intr : 1; /* Transmit interrupt status. */ + uint8_t dma_intr : 1; /* DMA interrupt status. */ + uint8_t unused : 5; +} EL_INTR_STAT; + +typedef struct { + uint32_t base_address; + int base_irq; + uint32_t bios_addr; + uint8_t maclocal[6]; /* configured MAC (local) address. */ + bool fISR; /* Internal interrupt flag. */ + int fDMA; /* Internal DMA active flag. */ + int fInReset; /* Internal in-reset flag. */ + uint8_t aPROM[8]; /* The PROM contents. Only 8 bytes addressable, R/O. */ + uint8_t aStationAddr[6]; /* The station address programmed by the guest, W/O. */ + uint16_t uGPBufPtr; /* General Purpose (GP) Buffer Pointer, R/W. */ + uint16_t uRCVBufPtr; /* Receive (RCV) Buffer Pointer, R/W. */ + /** Transmit Command Register, W/O. */ + union { + uint8_t XmitCmdReg; + EL_XMT_CMD XmitCmd; + }; + /** Transmit Status Register, R/O. */ + union { + uint8_t XmitStatReg; + EL_XMT_STAT XmitStat; + }; + /** Receive Command Register, W/O. */ + union { + uint8_t RcvCmdReg; + EL_RCV_CMD RcvCmd; + }; + /** Receive Status Register, R/O. */ + union { + uint8_t RcvStatReg; + EL_RCV_STAT RcvStat; + }; + /** Auxiliary Command Register, W/O. */ + union { + uint8_t AuxCmdReg; + EL_AUX_CMD AuxCmd; + }; + /** Auxiliary Status Register, R/O. */ + union { + uint8_t AuxStatReg; + EL_AUX_STAT AuxStat; + }; + int fLinkUp; /* If set the link is currently up. */ + int fLinkTempDown; /* If set the link is temporarily down because of a saved state load. */ + uint16_t cLinkDownReported; /* Number of times we've reported the link down. */ + uint16_t cLinkRestorePostponed; /* Number of times we've postponed the link restore. */ + /* Internal interrupt state. */ + union { + uint8_t IntrStateReg; + EL_INTR_STAT IntrState; + }; + uint32_t cMsLinkUpDelay; /* MS to wait before we enable the link. */ + int dma_channel; + uint8_t abLoopBuf[ELNK_BUF_SIZE]; /* The loopback transmit buffer (avoid stack allocations). */ + uint8_t abRuntBuf[64]; /* The runt pad buffer (only really needs 60 bytes). */ + uint8_t abPacketBuf[ELNK_BUF_SIZE]; /* The packet buffer. */ + int dma_pos; + pc_timer_t timer_restore; + netcard_t *netcard; +} threec501_t; + +#ifdef ENABLE_3COM501_LOG +int threec501_do_log = ENABLE_3COM501_LOG; + +static void +threec501_log(const char *fmt, ...) +{ + va_list ap; + + if (threec501_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define threec501_log(fmt, ...) +#endif + +static void elnkSoftReset(threec501_t *dev); +static void elnkR3HardReset(threec501_t *dev); + +#ifndef ETHER_IS_MULTICAST /* Net/Open BSD macro it seems */ +# define ETHER_IS_MULTICAST(a) ((*(uint8_t *) (a)) & 1) +#endif + +#define ETHER_ADDR_LEN ETH_ALEN +#define ETH_ALEN 6 +#pragma pack(1) +struct ether_header /** @todo Use RTNETETHERHDR? */ +{ + uint8_t ether_dhost[ETH_ALEN]; /**< destination ethernet address */ + uint8_t ether_shost[ETH_ALEN]; /**< source ethernet address */ + uint16_t ether_type; /**< packet type ID field */ +}; +#pragma pack() + +static void +elnk_do_irq(threec501_t *dev, int set) +{ + if (set) + picint(1 << dev->base_irq); + else + picintc(1 << dev->base_irq); +} + +/** + * Checks if the link is up. + * @returns true if the link is up. + * @returns false if the link is down. + */ +static __inline int +elnkIsLinkUp(threec501_t *dev) +{ + return !dev->fLinkTempDown && dev->fLinkUp; +} + +/** + * Takes down the link temporarily if it's current status is up. + * + * This is used during restore and when replumbing the network link. + * + * The temporary link outage is supposed to indicate to the OS that all network + * connections have been lost and that it for instance is appropriate to + * renegotiate any DHCP lease. + * + * @param pThis The shared instance data. + */ +static void +elnkTempLinkDown(threec501_t *dev) +{ + if (dev->fLinkUp) { + dev->fLinkTempDown = 1; + dev->cLinkDownReported = 0; + dev->cLinkRestorePostponed = 0; + timer_set_delay_u64(&dev->timer_restore, (dev->cMsLinkUpDelay * 1000) * TIMER_USEC); + } +} + +/** + * @interface_method_impl{PDMDEVREG,pfnReset} + */ +static void +elnkR3Reset(void *priv) +{ + threec501_t *dev = (threec501_t *) priv; + + if (dev->fLinkTempDown) { + dev->cLinkDownReported = 0x1000; + dev->cLinkRestorePostponed = 0x1000; + timer_disable(&dev->timer_restore); + } + + /** @todo How to flush the queues? */ + elnkR3HardReset(dev); +} + +static void +elnkR3HardReset(threec501_t *dev) +{ + dev->fISR = false; + elnk_do_irq(dev, 0); + + /* Clear the packet buffer and station address. */ + memset(dev->abPacketBuf, 0, sizeof(dev->abPacketBuf)); + memset(dev->aStationAddr, 0, sizeof(dev->aStationAddr)); + + /* Reset the buffer pointers. */ + dev->uGPBufPtr = 0; + dev->uRCVBufPtr = 0; + + elnkSoftReset(dev); +} + + +/** + * Check if incoming frame matches the station address. + */ +static __inline int +padr_match(threec501_t *dev, const uint8_t *buf) +{ + struct ether_header *hdr = (struct ether_header *)buf; + int result; + + /* Checks own + broadcast as well as own + multicast. */ + result = (dev->RcvCmd.adr_match >= EL_ADRM_BCAST) && !memcmp(hdr->ether_dhost, dev->aStationAddr, 6); + + return result; +} + +/** + * Check if incoming frame is an accepted broadcast frame. + */ +static __inline int +padr_bcast(threec501_t *dev, const uint8_t *buf) +{ + static uint8_t aBCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + struct ether_header *hdr = (struct ether_header *)buf; + int result = (dev->RcvCmd.adr_match == EL_ADRM_BCAST) && !memcmp(hdr->ether_dhost, aBCAST, 6); + return result; +} + + +/** + * Check if incoming frame is an accepted multicast frame. + */ +static __inline int +padr_mcast(threec501_t *dev, const uint8_t *buf) +{ + struct ether_header *hdr = (struct ether_header *)buf; + int result = (dev->RcvCmd.adr_match == EL_ADRM_MCAST) && ETHER_IS_MULTICAST(hdr->ether_dhost); + return result; +} + +/** + * Update the device IRQ line based on internal state. + */ +static void +elnkUpdateIrq(threec501_t *dev) +{ + bool fISR = false; + + /* IRQ is active if any interrupt source is active and interrupts + * are enabled via RIDE or IRE. + */ + if (dev->IntrStateReg && (dev->AuxCmd.ride || dev->AuxCmd.ire)) + fISR = true; + +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: elnkUpdateIrq: fISR=%d\n", fISR); +#endif + + if (fISR != dev->fISR) { + elnk_do_irq(dev, fISR); + dev->fISR = fISR; + } +} + +/** + * Perform a software reset of the NIC. + */ +static void +elnkSoftReset(threec501_t *dev) +{ +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: elnkSoftReset\n"); +#endif + + /* Clear some of the user-visible register state. */ + dev->XmitCmdReg = 0; + dev->XmitStatReg = 0; + dev->RcvCmdReg = 0; + dev->RcvStatReg = 0; + dev->AuxCmdReg = 0; + dev->AuxStatReg = 0; + + /* The "stale receive status" is cleared by receiving an "interesting" packet. */ + dev->RcvStat.stale = 1; + + /* By virtue of setting the buffer control to system, transmit is set to busy. */ + dev->AuxStat.xmit_bsy = 1; + + /* Clear internal interrupt state. */ + dev->IntrStateReg = 0; + elnkUpdateIrq(dev); + + /* Note that a soft reset does not clear the packet buffer; software often + * assumes that it survives soft reset. The programmed station address is + * likewise not reset, and the buffer pointers are not reset either. + * Verified on a real 3C501. + */ + + /* No longer in reset state. */ + dev->fInReset = 0; +} + +/** + * Write incoming data into the packet buffer. + */ +static int +elnkReceiveLocked(void *priv, uint8_t *src, int size) +{ + threec501_t *dev = (threec501_t *) priv; + int is_padr = 0, is_bcast = 0, is_mcast = 0; + bool fLoopback = dev->RcvCmd.adr_match == EL_BCTL_LOOPBACK; + + union { + uint8_t RcvStatNewReg; + EL_RCV_STAT RcvStatNew; + } rcvstatnew; + + /* Drop everything if address matching is disabled. */ + if (dev->RcvCmd.adr_match == EL_ADRM_DISABLED) + return 0; + + /* Drop zero-length packets (how does that even happen?). */ + if (!size) + return 0; + + /* + * Drop all packets if the cable is not connected (and not in loopback). + */ + if (!elnkIsLinkUp(dev) && !fLoopback) + return 0; + + /* + * Do not receive further packets until receive status was read. + */ + if (dev->RcvStat.stale == 0) + return 0; + +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: size on wire=%d, RCV ptr=%u\n", size, dev->uRCVBufPtr); +#endif + + /* + * Perform address matching. Packets which do not pass the address + * filter are always ignored. + */ + /// @todo cbToRecv must be 6 or more (complete address) + if ((dev->RcvCmd.adr_match == EL_ADRM_PROMISC) /* promiscuous enabled */ + || (is_padr = padr_match(dev, src)) + || (is_bcast = padr_bcast(dev, src)) + || (is_mcast = padr_mcast(dev, src))) { + uint8_t *dst = dev->abPacketBuf + dev->uRCVBufPtr; + +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501 Packet passed address filter (is_padr=%d, is_bcast=%d, is_mcast=%d), size=%d\n", is_padr, is_bcast, is_mcast, size); +#endif + + /* Receive status is evaluated from scratch. The stale bit must remain set until we know better. */ + rcvstatnew.RcvStatNewReg = 0; + rcvstatnew.RcvStatNew.stale = 1; + dev->RcvStatReg = 0x80; + + /* Detect errors: Runts, overflow, and FCS errors. + * NB: Dribble errors can not happen because we can only receive an + * integral number of bytes. FCS errors are only possible in loopback + * mode in case the FCS is deliberately corrupted. + */ + + /* See if we need to pad, and how much. Have to be careful because the + * Receive Buffer Pointer might be near the end of the buffer. + */ + if (size < 60) { + /* In loopback mode only, short packets are flagged as errors because + * diagnostic tools want to see the errors. Otherwise they're padded to + * minimum length (if packet came over the wire, it should have been + * properly padded). + */ + /// @todo This really is kind of wrong. We shouldn't be doing any + /// padding here, it should be done by the sending side! + if (!fLoopback) { + memset(dev->abRuntBuf, 0, sizeof(dev->abRuntBuf)); + memcpy(dev->abRuntBuf, src, size); + size = 60; + src = dev->abRuntBuf; + } else { +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501 runt, size=%d\n", size); +#endif + rcvstatnew.RcvStatNew.runt = 1; + } + } + + /* We don't care how big the frame is; if it fits into the buffer, all is + * good. But conversely if the Receive Buffer Pointer is initially near the + * end of the buffer, a small frame can trigger an overflow. + */ + if ((dev->uRCVBufPtr + size) <= ELNK_BUF_SIZE) + rcvstatnew.RcvStatNew.no_ovf = 1; + else { +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501 overflow, size=%d\n", size); +#endif + rcvstatnew.RcvStatNew.oflow = 1; + } + + if (fLoopback && dev->AuxCmd.xmit_bf) { +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501 bad FCS\n"); +#endif + rcvstatnew.RcvStatNew.fcs = 1; + } + + /* Error-free packets are considered good. */ + if (rcvstatnew.RcvStatNew.no_ovf && !rcvstatnew.RcvStatNew.fcs && !rcvstatnew.RcvStatNew.runt) + rcvstatnew.RcvStatNew.good = 1; + + uint16_t cbCopy = (uint16_t)MIN(ELNK_BUF_SIZE - dev->uRCVBufPtr, size); + + /* All packets that passed the address filter are copied to the buffer. */ + + /* Copy incoming data to the packet buffer. NB: Starts at the current + * Receive Buffer Pointer position. + */ + memcpy(dst, src, cbCopy); + + /* Packet length is indicated via the receive buffer pointer. */ + dev->uRCVBufPtr = (dev->uRCVBufPtr + cbCopy) & ELNK_GP_MASK; + +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501 Received packet, size=%d, RP=%u\n", cbCopy, dev->uRCVBufPtr); +#endif + + /* + * If one of the "interesting" conditions was hit, stop receiving until + * the status register is read (mark it not stale). + * NB: The precise receive logic is not very well described in the EtherLink + * documentation. It was refined using the 3C501.EXE diagnostic utility. + */ + if ( (rcvstatnew.RcvStatNew.good && dev->RcvCmd.acpt_good) + || (rcvstatnew.RcvStatNew.no_ovf && dev->RcvCmd.det_eof) + || (rcvstatnew.RcvStatNew.runt && dev->RcvCmd.det_runt) + || (rcvstatnew.RcvStatNew.dribble && dev->RcvCmd.det_drbl) + || (rcvstatnew.RcvStatNew.fcs && dev->RcvCmd.det_fcs) + || (rcvstatnew.RcvStatNew.oflow && dev->RcvCmd.det_ofl)) { + dev->AuxStat.recv_bsy = 0; + dev->IntrState.recv_intr = 1; + rcvstatnew.RcvStatNew.stale = 0; /* Prevents further receive until set again. */ + } + + /* Finally update the receive status. */ + dev->RcvStat = rcvstatnew.RcvStatNew; + +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: RcvCmd=%02X, RcvStat=%02X, RCVBufPtr=%u\n", dev->RcvCmdReg, dev->RcvStatReg, dev->uRCVBufPtr); +#endif + + elnkUpdateIrq(dev); + } + + return 1; +} + +/** + * Actually try transmit frames. + * + * @threads TX or EMT. + */ +static void +elnkAsyncTransmit(threec501_t *dev) +{ + /* + * Just drop it if not transmitting. Can happen with delayed transmits + * if transmit was disabled in the meantime. + */ + if (!dev->AuxStat.xmit_bsy) { +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: Nope, xmit disabled\n"); +#endif + return; + } + + if (((dev->AuxCmd.buf_ctl != EL_BCTL_XMT_RCV) && (dev->AuxCmd.buf_ctl != EL_BCTL_LOOPBACK))) { +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: Nope, not in xmit-then-receive or loopback state\n"); +#endif + return; + } + + /* + * Blast out data from the packet buffer. + */ + do { + /* Don't send anything when the link is down. */ + if ((!elnkIsLinkUp(dev) + && dev->cLinkDownReported > ELNK_MAX_LINKDOWN_REPORTED)) + break; + + bool const fLoopback = dev->AuxCmd.buf_ctl == EL_BCTL_LOOPBACK; + + /* + * Sending is easy peasy, there is by definition always + * a complete packet on hand. + */ + const unsigned cb = ELNK_BUF_SIZE - ELNK_GP(dev); /* Packet size. */ +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: cb=%d, loopback=%d.\n", cb, fLoopback); +#endif + + dev->XmitStatReg = 0; /* Clear transmit status before filling it out. */ + + if (elnkIsLinkUp(dev) || fLoopback) { + if (cb <= MAX_FRAME) { + if (fLoopback) { + elnkReceiveLocked(dev, &dev->abPacketBuf[ELNK_GP(dev)], cb); + } else { +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: elnkAsyncTransmit: transmit loopbuf xmit pos = %d\n", cb); +#endif + network_tx(dev->netcard, &dev->abPacketBuf[ELNK_GP(dev)], cb); + } + dev->XmitStat.ready = 1; + } else { + /* Signal error, as this violates the Ethernet specs. */ + /** @todo check if the correct error is generated. */ +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: illegal giant frame (%u bytes) -> signalling error\n", cb); +#endif + ; + } + } else { + /* Signal a transmit error pretending there was a collision. */ + dev->cLinkDownReported++; + dev->XmitStat.coll = 1; + } + + /* Transmit officially done, update register state. */ + dev->AuxStat.xmit_bsy = 0; + dev->IntrState.xmit_intr = !!(dev->XmitCmdReg & dev->XmitStatReg); +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: XmitCmd=%02X, XmitStat=%02X\n", dev->XmitCmdReg, dev->XmitStatReg); +#endif + + /* NB: After a transmit, the GP Buffer Pointer points just past + * the end of the packet buffer (3C501 diagnostics). + */ + dev->uGPBufPtr = ELNK_BUF_SIZE; + + /* NB: The buffer control does *not* change to Receive and stays the way it was. */ + if (!fLoopback) { + dev->AuxStat.recv_bsy = 1; /* Receive Busy now set until a packet is received. */ + } + } while (0); /* No loop, because there isn't ever more than one packet to transmit. */ + + elnkUpdateIrq(dev); +} + +static void +elnkCsrWrite(threec501_t *dev, uint8_t data) +{ + bool fTransmit = false; + bool fReceive = false; + bool fDMAR; + int mode; + + union { + uint8_t reg; + EL_AUX_CMD val; + } auxcmd; + + auxcmd.reg = data; + + /* Handle reset first. */ + if (dev->AuxCmd.reset != auxcmd.val.reset) { + if (auxcmd.val.reset) { + /* Card is placed into reset. Just set the flag. NB: When in reset + * state, we permit writes to other registers, but those have no + * effect and will be overwritten when the card is taken out of reset. + */ +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: Card going into reset\n"); +#endif + dev->fInReset = true; + + /* Many EtherLink drivers like to reset the card a lot. That can lead to + * packet loss if a packet was already received before the card was reset. + */ + } else { + /* Card is being taken out of reset. */ +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: Card going out of reset\n"); +#endif + elnkSoftReset(dev); + } + dev->AuxCmd.reset = auxcmd.val.reset; /* Update the reset bit, if nothing else. */ + } + + /* If the card is in reset, stop right here. */ + if (dev->fInReset) { +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: Reset\n"); +#endif + return; + } + + /* Evaluate DMA state. If it changed, we'll have to go back to R3. */ + fDMAR = auxcmd.val.dma_req && auxcmd.val.ride; + if (fDMAR != dev->fDMA) { + /* Start/stop DMA as requested. */ + dev->fDMA = fDMAR; + if (fDMAR) { + dma_set_drq(dev->dma_channel, fDMAR); + mode = dma_mode(dev->dma_channel); +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: DMA Mode = %02x.\n", mode & 0x0c); +#endif + if ((mode & 0x0c) == 0x04) { + while (dev->dma_pos < (ELNK_BUF_SIZE - ELNK_GP(dev))) { + dma_channel_write(dev->dma_channel, dev->abPacketBuf[ELNK_GP(dev) + dev->dma_pos]); + dev->dma_pos++; + } + } else { + while (dev->dma_pos < (ELNK_BUF_SIZE - ELNK_GP(dev))) { + int dma_data = dma_channel_read(dev->dma_channel); + dev->abPacketBuf[ELNK_GP(dev) + dev->dma_pos] = dma_data & 0xff; + dev->dma_pos++; + } + } + dev->uGPBufPtr = (dev->uGPBufPtr + dev->dma_pos) & ELNK_GP_MASK; + dma_set_drq(dev->dma_channel, 0); + dev->dma_pos = 0; + dev->IntrState.dma_intr = 1; + dev->AuxStat.dma_done = 1; + elnkUpdateIrq(dev); + } +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: DMARQ for channel %u set to %u\n", dev->dma_channel, fDMAR); +#endif + } + + /* Interrupt enable changes. */ + if ((dev->AuxCmd.ire != auxcmd.val.ire) || (dev->AuxCmd.ride != auxcmd.val.ride)) { + dev->AuxStat.ride = dev->AuxCmd.ride = auxcmd.val.ride; + dev->AuxCmd.ire = auxcmd.val.ire; /* NB: IRE is not visible in the aux status register. */ + } + + /* DMA Request changes. */ + if (dev->AuxCmd.dma_req != auxcmd.val.dma_req) { + dev->AuxStat.dma_req = dev->AuxCmd.dma_req = auxcmd.val.dma_req; + if (!auxcmd.val.dma_req) { + /* Clearing the DMA Request bit also clears the DMA Done status bit and any DMA interrupt. */ + dev->IntrState.dma_intr = 0; + dev->AuxStat.dma_done = 0; + } + } + + /* Packet buffer control changes. */ + if (dev->AuxCmd.buf_ctl != auxcmd.val.buf_ctl) { +#ifdef ENABLE_3COM501_LOG + static const char *apszBuffCntrl[4] = { "System", "Xmit then Recv", "Receive", "Loopback" }; + threec501_log("3Com501: Packet buffer control `%s' -> `%s'\n", apszBuffCntrl[dev->AuxCmd.buf_ctl], apszBuffCntrl[auxcmd.val.buf_ctl]); +#endif + if (auxcmd.val.buf_ctl == EL_BCTL_XMT_RCV) { + /* Transmit, then receive. */ + fTransmit = true; + dev->AuxStat.recv_bsy = 0; + } else if (auxcmd.val.buf_ctl == EL_BCTL_SYSTEM) { + dev->AuxStat.xmit_bsy = 1; /* Transmit Busy is set here and cleared once actual transmit completes. */ + dev->AuxStat.recv_bsy = 0; + } else if (auxcmd.val.buf_ctl == EL_BCTL_RECEIVE) { + /* Special case: If going from xmit-then-receive mode to receive mode, and we received + * a packet already (right after the receive), don't restart receive and lose the already + * received packet. + */ + if (!dev->uRCVBufPtr) + fReceive = true; + } else { + /* For loopback, we go through the regular transmit and receive path. That may be an + * overkill but the receive path is too complex for a special loopback-only case. + */ + fTransmit = true; + dev->AuxStat.recv_bsy = 1; /* Receive Busy now set until a packet is received. */ + } + dev->AuxStat.buf_ctl = dev->AuxCmd.buf_ctl = auxcmd.val.buf_ctl; + } + + /* NB: Bit 1 (xmit_bf, transmit packets with bad FCS) is a simple control + * bit which does not require special handling here. Just copy it over. + */ + dev->AuxStat.xmit_bf = dev->AuxCmd.xmit_bf = auxcmd.val.xmit_bf; + + /* There are multiple bits that affect interrupt state. Handle them now. */ + elnkUpdateIrq(dev); + + /* After fully updating register state, do a transmit (including loopback) or receive. */ + if (fTransmit) + elnkAsyncTransmit(dev); + else if (fReceive) { + dev->AuxStat.recv_bsy = 1; /* Receive Busy now set until a packet is received. */ + } +} + +static uint8_t +threec501_read(uint16_t addr, void *priv) +{ + threec501_t *dev = (threec501_t *) priv; + uint8_t retval = 0xff; + + switch (addr & 0x0f) { + case 0x00: /* Receive status register aliases. The SEEQ 8001 */ + case 0x02: /* EDLC clearly only decodes one bit for reads. */ + case 0x04: + case 0x06: /* Receive status register. */ + retval = dev->RcvStatReg; + dev->RcvStat.stale = 1; /* Allows further reception. */ + dev->IntrState.recv_intr = 0; /* Reading clears receive interrupt. */ + elnkUpdateIrq(dev); + break; + + case 0x01: /* Transmit status register aliases. */ + case 0x03: + case 0x05: + case 0x07: /* Transmit status register. */ + retval = dev->XmitStatReg; + dev->IntrState.xmit_intr = 0; /* Reading clears transmit interrupt. */ + elnkUpdateIrq(dev); + break; + + case 0x08: /* GP Buffer pointer LSB. */ + retval = (dev->uGPBufPtr & 0xff); + break; + case 0x09: /* GP Buffer pointer MSB. */ + retval = (dev->uGPBufPtr >> 8); + break; + + case 0x0a: /* RCV Buffer pointer LSB. */ + retval = (dev->uRCVBufPtr & 0xff); + break; + case 0x0b: /* RCV Buffer pointer MSB. */ + retval = (dev->uRCVBufPtr >> 8); + break; + + case 0x0c: /* Ethernet address PROM window. */ + case 0x0d: /* Alias. */ + /* Reads use low 3 bits of GP buffer pointer, no auto-increment. */ + retval = dev->aPROM[dev->uGPBufPtr & 7]; + break; + + case 0x0e: /* Auxiliary status register. */ + retval = dev->AuxStatReg; + break; + + case 0x0f: /* Buffer window. */ + /* Reads use low 11 bits of GP buffer pointer, auto-increment. */ + retval = dev->abPacketBuf[ELNK_GP(dev)]; + dev->uGPBufPtr = (dev->uGPBufPtr + 1) & ELNK_GP_MASK; + break; + } + + elnkUpdateIrq(dev); +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: read addr %x, value %x\n", addr & 0x0f, retval); +#endif + return (retval); +} + +static uint8_t +threec501_nic_readb(uint16_t addr, void *priv) +{ + return threec501_read(addr, priv); +} + +static uint16_t +threec501_nic_readw(uint16_t addr, void *priv) +{ + return threec501_read(addr, priv) | (threec501_read(addr + 1, priv) << 8); +} + +static void +threec501_write(uint16_t addr, uint8_t value, void *priv) +{ + threec501_t *dev = (threec501_t *) priv; + int reg = (addr & 0x0f); + + switch (reg) { + case 0x00: /* Six bytes of station address. */ + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + dev->aStationAddr[reg] = value; + break; + + case 0x06: /* Receive command. */ + dev->RcvCmdReg = value; +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: Receive Command register set to %02X\n", dev->RcvCmdReg); +#endif + break; + + case 0x07: /* Transmit command. */ + dev->XmitCmdReg = value; +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: Transmit Command register set to %02X\n", dev->XmitCmdReg); +#endif + break; + + case 0x08: /* GP Buffer pointer LSB. */ + dev->uGPBufPtr = (dev->uGPBufPtr & 0xff00) | value; + break; + case 0x09: /* GP Buffer pointer MSB. */ + dev->uGPBufPtr = (dev->uGPBufPtr & 0x00ff) | (value << 8); + break; + + case 0x0a: /* RCV Buffer pointer clear. */ + dev->uRCVBufPtr = 0; +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: RCV Buffer Pointer cleared (%02X)\n", value); +#endif + break; + + case 0x0b: /* RCV buffer pointer MSB. */ + case 0x0c: /* Ethernet address PROM window. */ + case 0x0d: /* Undocumented. */ +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: Writing read-only register %02X!\n", reg); +#endif + break; + + case 0x0e: /* Auxiliary Command (CSR). */ + elnkCsrWrite(dev, value); + break; + + case 0x0f: /* Buffer window. */ + /* Writes use low 11 bits of GP buffer pointer, auto-increment. */ + if (dev->AuxCmd.buf_ctl != EL_BCTL_SYSTEM) { + /// @todo Does this still increment GPBufPtr? + break; + } + dev->abPacketBuf[ELNK_GP(dev)] = value; + dev->uGPBufPtr = (dev->uGPBufPtr + 1) & ELNK_GP_MASK; + break; + } + +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: write addr %x, value %x\n", reg, value); +#endif +} + +static void +threec501_nic_writeb(uint16_t addr, uint8_t value, void *priv) +{ + threec501_write(addr, value, priv); +} + +static void +threec501_nic_writew(uint16_t addr, uint16_t value, void *priv) +{ + threec501_write(addr, value & 0xff, priv); + threec501_write(addr + 1, value >> 8, priv); +} + +static int +elnkSetLinkState(void *priv, uint32_t link_state) +{ + threec501_t *dev = (threec501_t *) priv; + + if (link_state & NET_LINK_TEMP_DOWN) { + elnkTempLinkDown(dev); + return 1; + } + + bool link_up = !(link_state & NET_LINK_DOWN); + if (dev->fLinkUp != link_up) { + dev->fLinkUp = link_up; + if (link_up) { + dev->fLinkTempDown = 1; + dev->cLinkDownReported = 0; + dev->cLinkRestorePostponed = 0; + timer_set_delay_u64(&dev->timer_restore, (dev->cMsLinkUpDelay * 1000) * TIMER_USEC); + } else { + dev->cLinkDownReported = 0; + dev->cLinkRestorePostponed = 0; + } + } + + return 0; +} + +static void +elnkR3TimerRestore(void *priv) +{ + threec501_t *dev = (threec501_t *) priv; + + if ((dev->cLinkDownReported <= ELNK_MAX_LINKDOWN_REPORTED) && + (dev->cLinkRestorePostponed <= ELNK_MAX_LINKRST_POSTPONED)) { + timer_advance_u64(&dev->timer_restore, 1500000 * TIMER_USEC); + dev->cLinkRestorePostponed++; + } else { + dev->fLinkTempDown = 0; + } +} + +static void * +threec501_nic_init(const device_t *info) +{ + uint32_t mac; + threec501_t *dev; + + dev = malloc(sizeof(threec501_t)); + memset(dev, 0x00, sizeof(threec501_t)); + dev->maclocal[0] = 0x02; /* 02:60:8C (3Com OID) */ + dev->maclocal[1] = 0x60; + dev->maclocal[2] = 0x8C; + + dev->base_address = device_get_config_hex16("base"); + dev->base_irq = device_get_config_int("irq"); + dev->dma_channel = device_get_config_int("dma"); + + dev->fLinkUp = 1; + dev->cMsLinkUpDelay = 5000; + + /* See if we have a local MAC address configured. */ + mac = device_get_config_mac("mac", -1); + + /* + * Make this device known to the I/O system. + * PnP and PCI devices start with address spaces inactive. + */ + io_sethandler(dev->base_address, 0x10, + threec501_nic_readb, threec501_nic_readw, NULL, + threec501_nic_writeb, threec501_nic_writew, NULL, dev); + + /* Set up our BIA. */ + if (mac & 0xff000000) { + /* Generate new local MAC. */ + dev->maclocal[3] = random_generate(); + dev->maclocal[4] = random_generate(); + dev->maclocal[5] = random_generate(); + mac = (((int) dev->maclocal[3]) << 16); + mac |= (((int) dev->maclocal[4]) << 8); + mac |= ((int) dev->maclocal[5]); + device_set_config_mac("mac", mac); + } else { + dev->maclocal[3] = (mac >> 16) & 0xff; + dev->maclocal[4] = (mac >> 8) & 0xff; + dev->maclocal[5] = (mac & 0xff); + } + + /* Initialize the PROM */ + memcpy(dev->aPROM, dev->maclocal, sizeof(dev->maclocal)); + dev->aPROM[6] = dev->aPROM[7] = 0; /* The two padding bytes. */ + +#ifdef ENABLE_3COM501_LOG + threec501_log("I/O=%04x, IRQ=%d, DMA=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", + dev->base_address, dev->base_irq, dev->dma_channel, + dev->aPROM[0], dev->aPROM[1], dev->aPROM[2], + dev->aPROM[3], dev->aPROM[4], dev->aPROM[5]); +#endif + + /* Reset the board. */ + elnkR3HardReset(dev); + + /* Attach ourselves to the network module. */ + dev->netcard = network_attach(dev, dev->aPROM, elnkReceiveLocked, elnkSetLinkState); + + timer_add(&dev->timer_restore, elnkR3TimerRestore, dev, 0); + + return (dev); +} + +static void +threec501_nic_close(void *priv) +{ + threec501_t *dev = (threec501_t *) priv; + +#ifdef ENABLE_3COM501_LOG + threec501_log("3Com501: closed\n"); +#endif + + free(dev); +} + +static const device_config_t threec501_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x300, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "0x280", .value = 0x280 }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x310", .value = 0x310 }, + { .description = "0x320", .value = 0x320 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 3, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2/9", .value = 9 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 6", .value = 6 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { + .name = "dma", + .description = "DMA channel", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 3, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 2", .value = 2 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + }, + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t threec501_device = { + .name = "3Com EtherLink (3c500/3c501)", + .internal_name = "3c501", + .flags = DEVICE_ISA, + .local = 0, + .init = threec501_nic_init, + .close = threec501_nic_close, + .reset = elnkR3Reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = threec501_config +}; diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index 5123da265..07dcc1a43 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -1,26 +1,26 @@ /* - * 86Box An emulator of (mostly) x86-based PC systems and devices, - * using the ISA, EISA, VLB, MCA, and PCI system buses, - * roughly spanning the era between 1981 and 1995. + * 86Box An emulator of (mostly) x86-based PC systems and devices, + * using the ISA, EISA, VLB, MCA, and PCI system buses, + * roughly spanning the era between 1981 and 1995. * - * This file is part of the 86Box Project. + * This file is part of the 86Box Project. * - * Implementation of the following network controllers: - * - 3Com Etherlink II 3c503 (ISA 8-bit). + * Implementation of the following network controllers: + * - 3Com Etherlink II 3c503 (ISA 8-bit). * * * - * Based on @(#)3c503.cpp Carl (MAME) + * Based on @(#)3c503.cpp Carl (MAME) * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, - * Carl, + * Authors: TheCollector1995, + * Miran Grca, + * Fred N. van Kempen, + * Carl, * - * Copyright 2018 TheCollector1995. - * Copyright 2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - * Portions Copyright (C) 2018 MAME Project + * Copyright 2018 TheCollector1995. + * Copyright 2018 Miran Grca. + * Copyright 2017-2018 Fred N. van Kempen. + * Portions Copyright (C) 2018 MAME Project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index bc8f79843..255749e4e 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of the DP8390 Network Interface Controller used by - * the WD family, NE1000/NE2000 family, and 3Com 3C503 NIC's. + * Emulation of the DP8390 Network Interface Controller used by + * the WD family, NE1000/NE2000 family, and 3Com 3C503 NIC's. * * * - * Authors: Miran Grca, - * Bochs project, + * Authors: Miran Grca, + * Bochs project, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Bochs project. + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Bochs project. */ #include #include diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 84b7a5ca8..e1f62c874 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of the AMD PCnet LANCE NIC controller for both the ISA, VLB, - * and PCI buses. + * Emulation of the AMD PCnet LANCE NIC controller for both the ISA, VLB, + * and PCI buses. * * * - * Authors: Miran Grca, - * TheCollector1995, - * Antony T Curtis + * Authors: Miran Grca, + * TheCollector1995, + * Antony T Curtis * - * Copyright 2004-2019 Antony T Curtis - * Copyright 2016-2019 Miran Grca. + * Copyright 2004-2019 Antony T Curtis + * Copyright 2016-2019 Miran Grca. */ #ifdef _WIN32 # include @@ -756,11 +756,11 @@ padr_match(nic_t *dev, const uint8_t *buf, int size) result = !CSR_DRCVPA(dev) && !memcmp(hdr->ether_dhost, padr, 6); pcnet_log(3, "%s: packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " - "padr=%02x:%02x:%02x:%02x:%02x:%02x => %d\n", - dev->name, - hdr->ether_dhost[0], hdr->ether_dhost[1], hdr->ether_dhost[2], - hdr->ether_dhost[3], hdr->ether_dhost[4], hdr->ether_dhost[5], - padr[0], padr[1], padr[2], padr[3], padr[4], padr[5], result); + "padr=%02x:%02x:%02x:%02x:%02x:%02x => %d\n", + dev->name, + hdr->ether_dhost[0], hdr->ether_dhost[1], hdr->ether_dhost[2], + hdr->ether_dhost[3], hdr->ether_dhost[4], hdr->ether_dhost[5], + padr[0], padr[1], padr[2], padr[3], padr[4], padr[5], result); return result; } @@ -944,13 +944,13 @@ pcnetInit(nic_t *dev) dev->GCUpperPhys = 0; PCNET_INIT(); pcnet_log(3, "%s: initblk.rlen=%#04x, initblk.tlen=%#04x\n", - dev->name, initblk.rlen, initblk.tlen); + dev->name, initblk.rlen, initblk.tlen); } else { struct INITBLK16 initblk; dev->GCUpperPhys = (0xff00 & (uint32_t) dev->aCSR[2]) << 16; PCNET_INIT(); pcnet_log(3, "%s: initblk.rlen=%#04x, initblk.tlen=%#04x\n", - dev->name, initblk.rlen, initblk.tlen); + dev->name, initblk.rlen, initblk.tlen); } #undef PCNET_INIT @@ -985,9 +985,9 @@ pcnetInit(nic_t *dev) CSR_CXST(dev) = CSR_CXBC(dev) = CSR_NXST(dev) = CSR_NXBC(dev) = 0; pcnet_log(1, "%s: Init: SWSTYLE=%d GCRDRA=%#010x[%d] GCTDRA=%#010x[%d]%s\n", - dev->name, BCR_SWSTYLE(dev), - dev->GCRDRA, CSR_RCVRL(dev), dev->GCTDRA, CSR_XMTRL(dev), - !dev->fSignalRxMiss ? " (CSR0_MISS disabled)" : ""); + dev->name, BCR_SWSTYLE(dev), + dev->GCRDRA, CSR_RCVRL(dev), dev->GCTDRA, CSR_XMTRL(dev), + !dev->fSignalRxMiss ? " (CSR0_MISS disabled)" : ""); if (dev->GCRDRA & (dev->iLog2DescSize - 1)) pcnet_log(1, "%s: Warning: Misaligned RDRA\n", dev->name); @@ -1072,7 +1072,7 @@ pcnetRdtePoll(nic_t *dev) */ if (++dev->uCntBadRMD < 50) pcnet_log(1, "%s: BAD RMD ENTRIES AT %#010x (i=%d)\n", - dev->name, addr, i); + dev->name, addr, i); return; } @@ -1098,7 +1098,7 @@ pcnetRdtePoll(nic_t *dev) */ if (++dev->uCntBadRMD < 50) pcnet_log(1, "%s: BAD RMD ENTRIES + AT %#010x (i=%d)\n", - dev->name, addr, i); + dev->name, addr, i); return; } @@ -1126,7 +1126,7 @@ pcnetTdtePoll(nic_t *dev, TMD *tmd) if (tmd->tmd1.ones != 15) { pcnet_log(1, "%s: BAD TMD XDA=%#010x\n", - dev->name, PHYSADDR(dev, cxda)); + dev->name, PHYSADDR(dev, cxda)); return 0; } @@ -1182,7 +1182,7 @@ pcnetCalcPacketLen(nic_t *dev, int cb) } if (tmd.tmd1.ones != 15) { pcnet_log(1, "%s: BAD TMD XDA=%#010x\n", - dev->name, PHYSADDR(dev, addrDesc)); + dev->name, PHYSADDR(dev, addrDesc)); pcnet_log(3, "%s: pcnetCalcPacketLen: bad TMD, return %u\n", dev->name, cbPacket); return cbPacket; } @@ -1228,9 +1228,9 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) return 0; pcnet_log(1, "%s: pcnetReceiveNoSync: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", dev->name, - buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], - size); + buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], + size); /* * Perform address matching. @@ -1411,7 +1411,7 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) dev->aCSR[0] |= 0x0400; pcnet_log(1, "%s: RINT set, RCVRC=%d CRDA=%#010x\n", dev->name, - CSR_RCVRC(dev), PHYSADDR(dev, CSR_CRDA(dev))); + CSR_RCVRC(dev), PHYSADDR(dev, CSR_CRDA(dev))); /* guest driver is owner: force repoll of current and next RDTEs */ CSR_CRST(dev) = 0; @@ -1574,7 +1574,7 @@ pcnetAsyncTransmit(nic_t *dev) CSR_XMTRC(dev) = CSR_XMTRL(dev); else CSR_XMTRC(dev) - --; + --; TMD dummy; if (!pcnetTdtePoll(dev, &dummy)) { @@ -1629,7 +1629,7 @@ pcnetAsyncTransmit(nic_t *dev) CSR_XMTRC(dev) = CSR_XMTRL(dev); else CSR_XMTRC(dev) - --; + --; break; } } /* the loop */ @@ -1897,7 +1897,7 @@ pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val) return; } pcnet_log(3, "%s: WRITE CSR%d, %#06x (hacked %#06x) (alt init)\n", dev->name, - rap, val, 1 + ~val); + rap, val, 1 + ~val); val = 1 + ~val; /* @@ -2984,12 +2984,12 @@ pcnet_init(const device_t *info) } pcnet_log(2, "%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, dev->base_address, dev->base_irq, - dev->aPROM[0], dev->aPROM[1], dev->aPROM[2], - dev->aPROM[3], dev->aPROM[4], dev->aPROM[5]); + dev->name, dev->base_address, dev->base_irq, + dev->aPROM[0], dev->aPROM[1], dev->aPROM[2], + dev->aPROM[3], dev->aPROM[4], dev->aPROM[5]); pcnet_log(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, - dev->is_pci ? "PCI" : "VLB/ISA", dev->base_address, dev->base_irq); + dev->is_pci ? "PCI" : "VLB/ISA", dev->base_address, dev->base_irq); /* Reset the board. */ pcnetHardReset(dev); @@ -3065,6 +3065,8 @@ static const device_config_t pcnet_isa_config[] = { { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 9", .value = 9 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "IRQ 11", .value = 11 }, { .description = "" } }, }, @@ -3124,6 +3126,8 @@ static const device_config_t pcnet_vlb_config[] = { { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 9", .value = 9 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "IRQ 11", .value = 11 }, { .description = "" } }, }, diff --git a/src/network/net_plip.c b/src/network/net_plip.c index 158e64764..58274e62a 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Emulation of a PLIP parallel port network device. + * Emulation of a PLIP parallel port network device. * - * Tested against the Linux plip.c driver and the DOS plip.com - * packet driver. PLIP is not particularly fast, as it's a 4-bit - * half-duplex protocol operating over SPP. + * Tested against the Linux plip.c driver and the DOS plip.com + * packet driver. PLIP is not particularly fast, as it's a 4-bit + * half-duplex protocol operating over SPP. * * * - * Author: RichardG, - * Copyright 2020 RichardG. + * Authors: RichardG, + * Copyright 2020 RichardG. */ #include #include diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 89c658e64..35dfb52bb 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handle SLiRP library processing. + * Handle SLiRP library processing. * - * Some of the code was borrowed from libvdeslirp - * + * Some of the code was borrowed from libvdeslirp + * * * * - * Authors: Fred N. van Kempen, - * RichardG, + * Authors: Fred N. van Kempen, + * RichardG, * - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2020 RichardG. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2020 RichardG. */ #include #include @@ -26,7 +26,6 @@ #include #include #include -#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> @@ -38,6 +37,10 @@ #include <86box/ini.h> #include <86box/config.h> #include <86box/video.h> + +#define _SSIZE_T_DEFINED +#include + #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # include @@ -414,7 +417,7 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, void *priv) /* Set up port forwarding. */ int udp, external, internal, i = 0; char category[32]; - snprintf(category, sizeof(category), "SLiRP Port Forwarding #%i", card->card_num + 1); + snprintf(category, sizeof(category), "SLiRP Port Forwarding #%d", card->card_num + 1); char key[20]; while (1) { sprintf(key, "%d_protocol", i); diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 4142fbd38..c820e7444 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -1,26 +1,26 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the following network controllers: - * - SMC/WD 8003E (ISA 8-bit); - * - SMC/WD 8013EBT (ISA 16-bit); - * - SMC/WD 8013EP/A (MCA). + * Implementation of the following network controllers: + * - SMC/WD 8003E (ISA 8-bit); + * - SMC/WD 8013EBT (ISA 16-bit); + * - SMC/WD 8013EP/A (MCA). * * * - * Authors: Fred N. van Kempen, - * TheCollector1995, - * Miran Grca, - * Peter Grehan, + * Authors: Fred N. van Kempen, + * TheCollector1995, + * Miran Grca, + * Peter Grehan, * - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2016-2019 Miran Grca. - * Portions Copyright (C) 2002 MandrakeSoft S.A. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2016-2019 Miran Grca. + * Portions Copyright (C) 2002 MandrakeSoft S.A. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -548,7 +548,7 @@ wd_mca_write(int port, uint8_t val, void *priv) dev->base_address = (dev->pos_regs[2] & 0xfe) << 4; dev->ram_addr = (dev->pos_regs[3] & 0xfc) << 12; - dev->irq = irq[dev->pos_regs[5] & 0x02]; + dev->irq = irq[dev->pos_regs[5] & 0x03]; /* Initialize the device if fully configured. */ /* Register (new) I/O handler. */ diff --git a/src/network/network.c b/src/network/network.c index 9b4c9e4b9..f6e9eb565 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -55,7 +55,7 @@ #include #include #ifndef _WIN32 -#include +# include #endif /* _WIN32 */ #include #define HAVE_STDARG_H @@ -67,6 +67,7 @@ #include <86box/ui.h> #include <86box/timer.h> #include <86box/network.h> +#include <86box/net_3c501.h> #include <86box/net_3c503.h> #include <86box/net_ne2000.h> #include <86box/net_pcnet.h> @@ -95,6 +96,7 @@ static const device_t net_none_device = { static const device_t *net_cards[] = { &net_none_device, + &threec501_device, &threec503_device, &pcnet_am79c960_device, &pcnet_am79c961_device, @@ -118,7 +120,7 @@ static const device_t *net_cards[] = { }; netcard_conf_t net_cards_conf[NET_CARD_MAX]; -int net_card_current = 0; +uint16_t net_card_current = 0; /* Global variables. */ int network_ndev; @@ -126,7 +128,7 @@ netdev_t network_devs[NET_HOST_INTF_MAX]; /* Local variables. */ -#if defined ENABLE_NETWORK_LOG && !defined(_WIN32) +#if defined ENABLE_NETWORK_LOG && !defined(_WIN32) int network_do_log = ENABLE_NETWORK_LOG; static FILE *network_dump = NULL; static mutex_t *network_dump_mutex; diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c index 53eb6804a..69110cb34 100644 --- a/src/network/pcap_if.c +++ b/src/network/pcap_if.c @@ -288,7 +288,7 @@ main(int argc, char **argv) return (1); } -/* Looks good, go and listen.. */ + /* Looks good, go and listen.. */ i = start_cap(interfaces[i - 1].device); dynld_close(pcap_handle); diff --git a/src/network/slirp/tinyglib.c b/src/network/slirp/tinyglib.c index 9504ff3af..702c39ad7 100644 --- a/src/network/slirp/tinyglib.c +++ b/src/network/slirp/tinyglib.c @@ -28,18 +28,16 @@ g_spawn_async_with_fds(const gchar *working_directory, gchar **argv, return 0; } - /* Needs bounds checking, but not really used by libslirp. */ GString * g_string_new(gchar *base) { char *ret = malloc(4096); if (base) - strcpy(ret, base); + strcpy(ret, base); return ret; } - /* Unimplemented, as with anything related to GString. */ gchar * g_string_free(GString *string, gboolean free_segment) @@ -47,87 +45,84 @@ g_string_free(GString *string, gboolean free_segment) return (free_segment ? NULL : string); } - /* Implementation borrowed from GLib itself. */ gchar * g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle) { if (haystack_len < 0) - return strstr(haystack, needle); + return strstr(haystack, needle); else { - const gchar *p = haystack; - gsize needle_len = strlen(needle); - gsize haystack_len_unsigned = haystack_len; - const gchar *end; - gsize i; + const gchar *p = haystack; + gsize needle_len = strlen(needle); + gsize haystack_len_unsigned = haystack_len; + const gchar *end; + gsize i; - if (needle_len == 0) - return (gchar *) haystack; + if (needle_len == 0) + return (gchar *) haystack; - if (haystack_len_unsigned < needle_len) - return NULL; + if (haystack_len_unsigned < needle_len) + return NULL; - end = haystack + haystack_len - needle_len; + end = haystack + haystack_len - needle_len; - while (p <= end && *p) { - for (i = 0; i < needle_len; i++) - if (p[i] != needle[i]) - goto next; + while (p <= end && *p) { + for (i = 0; i < needle_len; i++) + if (p[i] != needle[i]) + goto next; - return (gchar *)p; + return (gchar *) p; next: - p++; - } + p++; + } - return NULL; + return NULL; } } - /* Implementation borrowed from GLib itself. */ guint g_strv_length(gchar **str_array) { guint i = 0; while (str_array[i] != NULL) - ++i; + ++i; return i; } /* Implementation borrowed from GLib itself. */ gsize -g_strlcpy (gchar *dest, - const gchar *src, - gsize dest_size) +g_strlcpy(gchar *dest, + const gchar *src, + gsize dest_size) { - gchar *d = dest; - const gchar *s = src; - gsize n = dest_size; + gchar *d = dest; + const gchar *s = src; + gsize n = dest_size; - if (dest == NULL) return 0; - if (src == NULL) return 0; + if (dest == NULL) + return 0; + if (src == NULL) + return 0; - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) - do - { - gchar c = *s++; + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) + do { + gchar c = *s++; - *d++ = c; - if (c == 0) - break; - } - while (--n != 0); + *d++ = c; + if (c == 0) + break; + } while (--n != 0); - /* If not enough room in dest, add NUL and traverse rest of src */ - if (n == 0) - { - if (dest_size != 0) - *d = 0; - while (*s++) - ; + /* If not enough room in dest, add NUL and traverse rest of src */ + if (n == 0) { + if (dest_size != 0) + *d = 0; + while (*s++) + ; } - return s - src - 1; /* count does not include NUL */ + return s - src - 1; /* count does not include NUL */ } diff --git a/src/nvr_ps2.c b/src/nvr_ps2.c index 47c8e86c0..b137cb81b 100644 --- a/src/nvr_ps2.c +++ b/src/nvr_ps2.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Handling of the PS/2 series CMOS devices. + * Handling of the PS/2 series CMOS devices. * * * diff --git a/src/pci.c b/src/pci.c index 6b51b0769..7b4464407 100644 --- a/src/pci.c +++ b/src/pci.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation the PCI bus. + * Implementation the PCI bus. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, - * Sarah Walker, + * Authors: Miran Grca, + * Fred N. van Kempen, + * Sarah Walker, * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. */ #include #include @@ -404,9 +404,9 @@ pci_set_pmc(uint8_t pmc) io_sethandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_sethandler(0x0cfa, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfc, 4, - pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); + pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); } else if (pci_pmc && !(pmc & 0x01)) { io_removehandler(pci_base, pci_size, pci_type2_read, NULL, NULL, @@ -420,9 +420,9 @@ pci_set_pmc(uint8_t pmc) io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_removehandler(0x0cfa, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_removehandler(0x0cfc, 4, - pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); + pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -509,7 +509,7 @@ static uint8_t pci_type2_read(uint16_t port, void *priv) { uint8_t slot = 0; - uint8_t ret = 0xff; + uint8_t ret = 0xff; if (port == 0xcf8) ret = pci_key | (pci_func << 1); @@ -862,11 +862,11 @@ pci_reset(void) io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_removehandler(0x0cfc, 4, - pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); + pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); io_removehandler(0x0cf8, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_removehandler(0x0cfa, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -1044,7 +1044,7 @@ pci_init(int type) } uint8_t -pci_register_bus() +pci_register_bus(void) { return last_pci_bus++; } diff --git a/src/pic.c b/src/pic.c index 1a5302ffb..b7ff54e37 100644 --- a/src/pic.c +++ b/src/pic.c @@ -9,6 +9,8 @@ * Implementation of the Intel PIC chip emulation, partially * ported from reenigne's XTCE. * + * + * * Authors: Andrew Jenner, * Miran Grca, * @@ -247,7 +249,7 @@ pic_callback(void *priv) } void -pic_reset() +pic_reset(void) { int is_at = IS_AT(machine); is_at = is_at || !strcmp(machine_get_internal_name(), "xi8088"); @@ -707,7 +709,7 @@ pic_irq_ack(void) } int -picinterrupt() +picinterrupt(void) { int i, ret = -1; diff --git a/src/pit.c b/src/pit.c index 392701056..27e1beaad 100644 --- a/src/pit.c +++ b/src/pit.c @@ -1,18 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Intel 8253/8254 Programmable Interval - * Timer. + * Implementation of the Intel 8253/8254 Programmable Interval + * Timer. * * * - * Author: Miran Grca, - * Copyright 2019 Miran Grca. + * Authors: Miran Grca, + * + * Copyright 2019 Miran Grca. */ #include #include diff --git a/src/pit_fast.c b/src/pit_fast.c index d029cf3ee..dac71aaec 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -1,18 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Intel 8253/8254 Programmable Interval - * Timer. + * Implementation of the Intel 8253/8254 Programmable Interval + * Timer. * * * - * Author: Miran Grca, - * Copyright 2019 Miran Grca. + * Authors: Miran Grca, + * + * Copyright 2019 Miran Grca. */ #include #include diff --git a/src/port_6x.c b/src/port_6x.c index a825b643c..88d8820b7 100644 --- a/src/port_6x.c +++ b/src/port_6x.c @@ -1,17 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Ports 61, 62, and 63 used by various - * machines. + * Implementation of Ports 61, 62, and 63 used by various + * machines. * - * Authors: Miran Grca, * - * Copyright 2021 Miran Grca. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. */ #include #include diff --git a/src/port_92.c b/src/port_92.c index 898f46c98..cbc419569 100644 --- a/src/port_92.c +++ b/src/port_92.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of Port 92 used by PS/2 machines and 386+ - * clones. + * Implementation of Port 92 used by PS/2 machines and 386+ + * clones. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2019 Miran Grca. + * Copyright 2019 Miran Grca. */ #include #include diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index 5990789bb..dd07121df 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(print OBJECT png.c prt_cpmap.c prt_escp.c prt_text.c prt_ps.c) diff --git a/src/printer/png.c b/src/printer/png.c index 56e2ccfc7..bb862a953 100644 --- a/src/printer/png.c +++ b/src/printer/png.c @@ -124,7 +124,7 @@ error: png_log("PNG: fatal error, bailing out, error = %i\n", errno); if (png != NULL) PNGFUNC(destroy_write_struct) - (&png, &info); + (&png, &info); if (fp != NULL) (void) fclose(fp); return (0); @@ -206,7 +206,7 @@ png_write_rgb(char *fn, uint8_t *pix, int16_t w, int16_t h, uint16_t pitch, PALE error: if (png != NULL) PNGFUNC(destroy_write_struct) - (&png, &info); + (&png, &info); if (fp != NULL) (void) fclose(fp); return; diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 96d9bf86b..e0a83da31 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1997,7 +1997,7 @@ escp_init(void *lpt) if (ft_handle == NULL) { ft_handle = dynld_module(fn, ft_imports); if (ft_handle == NULL) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2110, (wchar_t *) IDS_2131); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132); return (NULL); } } @@ -2005,7 +2005,7 @@ escp_init(void *lpt) /* Initialize FreeType. */ if (ft_lib == NULL) { if (ft_Init_FreeType(&ft_lib)) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2110, (wchar_t *) IDS_2131); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132); dynld_close(ft_lib); ft_lib = NULL; return (NULL); diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 760bc5e17..0de04926d 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of a generic PostScript printer. + * Implementation of a generic PostScript printer. * * * - * Authors: David Hrdlička, + * Authors: David Hrdlička, * - * Copyright 2019 David Hrdlička. + * Copyright 2019 David Hrdlička. */ #include @@ -340,7 +340,7 @@ ps_init(void *lpt) /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); if (ghostscript_handle == NULL) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2114, (wchar_t *) IDS_2132); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2115, (wchar_t *) IDS_2133); else { if (gsapi_revision(&rev, sizeof(rev)) == 0) pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); @@ -350,7 +350,7 @@ ps_init(void *lpt) } } -/* Cache print folder path. */ + /* Cache print folder path. */ memset(dev->printer_path, 0x00, sizeof(dev->printer_path)); path_append_filename(dev->printer_path, usr_path, "printer"); if (!plat_dir_check(dev->printer_path)) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 63ebbbdef..7b3dfc929 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -1,3 +1,14 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# + # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) @@ -172,12 +183,10 @@ add_library(ui STATIC ../qt_resources.qrc ) - if(RTMIDI) target_compile_definitions(ui PRIVATE USE_RTMIDI) endif() - if(WIN32) enable_language(RC) target_sources(86Box PUBLIC ../win/86Box-qt.rc) diff --git a/src/qt/cocoa_mouse.hpp b/src/qt/cocoa_mouse.hpp index 8db79d9e8..af78abad6 100644 --- a/src/qt/cocoa_mouse.hpp +++ b/src/qt/cocoa_mouse.hpp @@ -2,13 +2,12 @@ #include #if QT_VERSION_MAJOR >= 6 -#define result_t qintptr +# define result_t qintptr #else -#define result_t long +# define result_t long #endif -class CocoaEventFilter : public QAbstractNativeEventFilter -{ +class CocoaEventFilter : public QAbstractNativeEventFilter { public: CocoaEventFilter() {}; ~CocoaEventFilter(); diff --git a/src/qt/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp index 5ad252f1a..c3d926285 100644 --- a/src/qt/evdev_mouse.cpp +++ b/src/qt/evdev_mouse.cpp @@ -26,63 +26,59 @@ #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/mouse.h> #include } -static std::vector> evdev_mice; -static std::atomic stopped = false; -static QThread* evdev_thread; +static std::vector> evdev_mice; +static std::atomic stopped = false; +static QThread *evdev_thread; static std::atomic evdev_mouse_rel_x = 0, evdev_mouse_rel_y = 0; -void evdev_mouse_poll() +void +evdev_mouse_poll() { - if (!evdev_mice.size() || !mouse_capture) - { + if (!evdev_mice.size() || !mouse_capture) { evdev_mouse_rel_x = 0; evdev_mouse_rel_y = 0; return; } - mouse_x = evdev_mouse_rel_x; - mouse_y = evdev_mouse_rel_y; + mouse_x = evdev_mouse_rel_x; + mouse_y = evdev_mouse_rel_y; evdev_mouse_rel_x = evdev_mouse_rel_y = 0; } -void evdev_thread_func() +void +evdev_thread_func() { - struct pollfd *pfds = (struct pollfd*)calloc(evdev_mice.size(), sizeof(struct pollfd)); - for (unsigned int i = 0; i < evdev_mice.size(); i++) - { - pfds[i].fd = libevdev_get_fd(evdev_mice[i].second); + struct pollfd *pfds = (struct pollfd *) calloc(evdev_mice.size(), sizeof(struct pollfd)); + for (unsigned int i = 0; i < evdev_mice.size(); i++) { + pfds[i].fd = libevdev_get_fd(evdev_mice[i].second); pfds[i].events = POLLIN; } - while (!stopped) - { + while (!stopped) { poll(pfds, evdev_mice.size(), 500); - for (unsigned int i = 0; i < evdev_mice.size(); i++) - { + for (unsigned int i = 0; i < evdev_mice.size(); i++) { struct input_event ev; if (pfds[i].revents & POLLIN) { - while (libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev) == 0) - { - if (ev.type == EV_REL && mouse_capture) - { - if (ev.code == REL_X) evdev_mouse_rel_x += ev.value; - if (ev.code == REL_Y) evdev_mouse_rel_y += ev.value; + while (libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev) == 0) { + if (ev.type == EV_REL && mouse_capture) { + if (ev.code == REL_X) + evdev_mouse_rel_x += ev.value; + if (ev.code == REL_Y) + evdev_mouse_rel_y += ev.value; } } } } } - for (unsigned int i = 0; i < evdev_mice.size(); i++) - { + for (unsigned int i = 0; i < evdev_mice.size(); i++) { libevdev_free(evdev_mice[i].second); evdev_mice[i].second = nullptr; close(evdev_mice[i].first); @@ -91,7 +87,8 @@ void evdev_thread_func() evdev_mice.clear(); } -void evdev_stop() +void +evdev_stop() { if (evdev_thread) { stopped = true; @@ -100,37 +97,32 @@ void evdev_stop() } } -void evdev_init() +void +evdev_init() { - if (evdev_thread) return; - for (int i = 0; i < 256; i++) - { + if (evdev_thread) + return; + for (int i = 0; i < 256; i++) { std::string evdev_device_path = "/dev/input/event" + std::to_string(i); - int fd = open(evdev_device_path.c_str(), O_NONBLOCK | O_RDONLY); - if (fd != -1) - { - libevdev* input_struct = nullptr; - int rc = libevdev_new_from_fd(fd, &input_struct); - if (rc <= -1) - { + int fd = open(evdev_device_path.c_str(), O_NONBLOCK | O_RDONLY); + if (fd != -1) { + libevdev *input_struct = nullptr; + int rc = libevdev_new_from_fd(fd, &input_struct); + if (rc <= -1) { close(fd); continue; - } - else - { - if (!libevdev_has_event_type(input_struct, EV_REL) || !libevdev_has_event_code(input_struct, EV_KEY, BTN_LEFT)) - { + } else { + if (!libevdev_has_event_type(input_struct, EV_REL) || !libevdev_has_event_code(input_struct, EV_KEY, BTN_LEFT)) { libevdev_free(input_struct); close(fd); continue; } evdev_mice.push_back(std::make_pair(fd, input_struct)); } - } - else if (errno == ENOENT) break; + } else if (errno == ENOENT) + break; } - if (evdev_mice.size() != 0) - { + if (evdev_mice.size() != 0) { evdev_thread = QThread::create(evdev_thread_func); evdev_thread->start(); atexit(evdev_stop); diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index d6ce352ef..d8fe563fe 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -244,11 +244,8 @@ msgstr "&Vyjmout" msgid "&Reload previous image" msgstr "&Načíst znova předchozí obraz" -msgid "&Image" -msgstr "&Obraz..." - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Složka..." msgid "Target &framerate" msgstr "&Cílová snímková frekvence" @@ -385,6 +382,12 @@ msgstr "Grafika:" msgid "Voodoo Graphics" msgstr "Použít grafický akcelerátor Voodoo" +msgid "IBM 8514/a Graphics" +msgstr "Grafika IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Grafika XGA" + msgid "Mouse:" msgstr "Myš:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Použít zvuk FLOAT32" +msgid "FM synth driver" +msgstr "FM synth driver" + +msgid "Nuked (more accurate)" +msgstr "Nuked (přesnější)" + +msgid "YMFM (faster)" +msgstr "YMFM (rychlejší)" + msgid "Network type:" msgstr "Druh sítě:" @@ -571,6 +583,9 @@ msgstr "Kontrola BPB" msgid "CD-ROM drives:" msgstr "Mechaniky CD-ROM:" +msgid "Earlier drive" +msgstr "Časná mechanika" + msgid "MO drives:" msgstr "Magnetooptické mechaniky:" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 2897b23f5..74fa56afa 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -29,7 +29,7 @@ msgid "&Hide status bar" msgstr "&Statusleiste ausblenden" msgid "Hide &toolbar" -msgstr "Werkzeugleiste &ausblenden" +msgstr "&Werkzeugleiste ausblenden" msgid "&Resizeable window" msgstr "&Größenverstellbares Fenster" @@ -244,11 +244,8 @@ msgstr "L&eer" msgid "&Reload previous image" msgstr "&Voriges Image neu laden" -msgid "&Image" -msgstr "&Image" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Verzeichnis..." msgid "Target &framerate" msgstr "Ziel&framerate" @@ -350,7 +347,7 @@ msgid "CPU type:" msgstr "CPU-Typ:" msgid "Speed:" -msgstr "Geschwindigkeit:" +msgstr "Takt:" msgid "FPU:" msgstr "FPU-Einheit:" @@ -385,6 +382,12 @@ msgstr "Videokarte:" msgid "Voodoo Graphics" msgstr "Voodoo-Grafik" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a-Grafik" + +msgid "XGA Graphics" +msgstr "XGA-Grafik" + msgid "Mouse:" msgstr "Maus:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "FLOAT32-Wiedergabe benutzen" +msgid "FM synth driver" +msgstr "FM-Synth-Treiber" + +msgid "Nuked (more accurate)" +msgstr "Nuked (genauer)" + +msgid "YMFM (faster)" +msgstr "YMFM (schneller)" + msgid "Network type:" msgstr "Netzwerktyp:" @@ -571,6 +583,9 @@ msgstr "BPB überprüfen" msgid "CD-ROM drives:" msgstr "CD-ROM-Laufwerke:" +msgid "Earlier drive" +msgstr "Früheres Laufwerk" + msgid "MO drives:" msgstr "MO-Laufwerke:" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 48e978f86..5575d9481 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -244,9 +244,6 @@ msgstr "E&mpty" msgid "&Reload previous image" msgstr "&Reload previous image" -msgid "&Image" -msgstr "&Image" - msgid "&Folder..." msgstr "&Folder..." @@ -385,6 +382,12 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a Graphics" + +msgid "XGA Graphics" +msgstr "XGA Graphics" + msgid "Mouse:" msgstr "Mouse:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Use FLOAT32 sound" +msgid "FM synth driver" +msgstr "FM synth driver" + +msgid "Nuked (more accurate)" +msgstr "Nuked (more accurate)" + +msgid "YMFM (faster)" +msgstr "YMFM (faster)" + msgid "Network type:" msgstr "Network type:" @@ -571,6 +583,9 @@ msgstr "Check BPB" msgid "CD-ROM drives:" msgstr "CD-ROM drives:" +msgid "Earlier drive" +msgstr "Earlier drive" + msgid "MO drives:" msgstr "MO drives:" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index a6b577322..e6652c057 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -244,9 +244,6 @@ msgstr "E&mpty" msgid "&Reload previous image" msgstr "&Reload previous image" -msgid "&Image" -msgstr "&Image" - msgid "&Folder..." msgstr "&Folder..." @@ -385,6 +382,12 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a Graphics" + +msgid "XGA Graphics" +msgstr "XGA Graphics" + msgid "Mouse:" msgstr "Mouse:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Use FLOAT32 sound" +msgid "FM synth driver" +msgstr "FM synth driver" + +msgid "Nuked (more accurate)" +msgstr "Nuked (more accurate)" + +msgid "YMFM (faster)" +msgstr "YMFM (faster)" + msgid "Network type:" msgstr "Network type:" @@ -571,6 +583,9 @@ msgstr "Check BPB" msgid "CD-ROM drives:" msgstr "CD-ROM drives:" +msgid "Earlier drive" +msgstr "Earlier drive" + msgid "MO drives:" msgstr "MO drives:" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 4c803a442..0a7014589 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -244,11 +244,8 @@ msgstr "E&xtraer disco" msgid "&Reload previous image" msgstr "&Recargar imagen previa" -msgid "&Image" -msgstr "&Imagen..." - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Carpeta..." msgid "Target &framerate" msgstr "&Tasa de refresco objetivo" @@ -385,6 +382,12 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a Graphics" + +msgid "XGA Graphics" +msgstr "XGA Graphics" + msgid "Mouse:" msgstr "Ratón:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Usar sonido FLOAT32" +msgid "FM synth driver" +msgstr "Controlador de sintet. FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (más preciso)" + +msgid "YMFM (faster)" +msgstr "YMFM (más rápido)" + msgid "Network type:" msgstr "Tipo de red:" @@ -571,6 +583,9 @@ msgstr "Chequear BPB" msgid "CD-ROM drives:" msgstr "Unidades de CD-ROM:" +msgid "Earlier drive" +msgstr "Unidad anterior" + msgid "MO drives:" msgstr "Unidades MO:" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 2bfc8c1fc..a5284844d 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -128,7 +128,7 @@ msgid "E&GA/(S)VGA settings" msgstr "&EGA/(S)VGA-asetukset" msgid "&Inverted VGA monitor" -msgstr "&VGA näyttö käänteisillä väreillä" +msgstr "&VGA-näyttö käänteisillä väreillä" msgid "VGA screen &type" msgstr "VGA-näytön &tyyppi" @@ -161,7 +161,7 @@ msgid "&Average" msgstr "&Keskiarvo" msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" -msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA-&yliskannaus" +msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA &yliskannaus" msgid "Change contrast for &monochrome display" msgstr "&Muuta harmaavärinäytön kontrastia" @@ -206,13 +206,13 @@ msgid "&About 86Box..." msgstr "&Tietoja 86Boxista..." msgid "&New image..." -msgstr "&Uusi levykuva..." +msgstr "&Uusi kasettikuva..." msgid "&Existing image..." -msgstr "&Olemassaoleva levykuva..." +msgstr "&Olemassaoleva kasettikuva..." msgid "Existing image (&Write-protected)..." -msgstr "Olemassaoleva levykuva (&kirjoitussuojattu)..." +msgstr "Olemassaoleva kasettikuva (&kirjoitussuojattu)..." msgid "&Record" msgstr "&Nauhoita" @@ -227,7 +227,7 @@ msgid "&Fast forward to the end" msgstr "Kelaa &loppuun" msgid "E&ject" -msgstr "&Poista asemasta" +msgstr "&Poista kasettipesästä" msgid "&Image..." msgstr "&ROM-moduulikuva..." @@ -244,11 +244,8 @@ msgstr "&Tyhjä" msgid "&Reload previous image" msgstr "&Lataa edellinen levykuva uudelleen" -msgid "&Image" -msgstr "L&evykuva" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Kansio..." msgid "Target &framerate" msgstr "&Kuvataajuustavoite" @@ -385,6 +382,12 @@ msgstr "Näytönohjain:" msgid "Voodoo Graphics" msgstr "Voodoo-grafiikkasuoritin" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a-grafiikkasuoritin" + +msgid "XGA Graphics" +msgstr "XGA-grafiikkasuoritin" + msgid "Mouse:" msgstr "Hiiri:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Käytä FLOAT32-ääntä" +msgid "FM synth driver" +msgstr "FM-syntetisaattoriohjain" + +msgid "Nuked (more accurate)" +msgstr "Nuked (tarkempi)" + +msgid "YMFM (faster)" +msgstr "YMFM (nopeampi)" + msgid "Network type:" msgstr "Verkon tyyppi:" @@ -571,6 +583,9 @@ msgstr "Tarkista BPB" msgid "CD-ROM drives:" msgstr "CD-ROM-asemat:" +msgid "Earlier drive" +msgstr "Aiemmat asemat" + msgid "MO drives:" msgstr "Magneettisoptiset asemat (MO):" @@ -1190,16 +1205,16 @@ msgid "5.25\" 1.3 GB" msgstr "5.25\" 1.3 Gt" msgid "Perfect RPM" -msgstr "Täydellinen kierrosluku" +msgstr "Täydellinen RPM" msgid "1% below perfect RPM" -msgstr "1% alle täydellisen kierrosluvun" +msgstr "1% alle täydellisen RPM:n" msgid "1.5% below perfect RPM" -msgstr "1.5% alle täydellisen kierrosluvun" +msgstr "1.5% alle täydellisen RPM:n" msgid "2% below perfect RPM" -msgstr "2% alle täydellisen kierrosluvun" +msgstr "2% alle täydellisen RPM:n" msgid "(System Default)" msgstr "(Järjestelmän oletus)" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index beb98e567..272d654c9 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -244,11 +244,8 @@ msgstr "E&jecter" msgid "&Reload previous image" msgstr "&Recharger image précedente" -msgid "&Image" -msgstr "&Image" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Dossier..." msgid "Target &framerate" msgstr "&Taux de rafraîchissement cible" @@ -385,6 +382,12 @@ msgstr "Vidéo:" msgid "Voodoo Graphics" msgstr "Graphique Voodoo" +msgid "IBM 8514/a Graphics" +msgstr "Graphique IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Graphique XGA" + msgid "Mouse:" msgstr "Souris:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Utiliser le son FLOAT32" +msgid "FM synth driver" +msgstr "Pilote de synthétiseur FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (plus précis)" + +msgid "YMFM (faster)" +msgstr "YMFM (plus rapide)" + msgid "Network type:" msgstr "Type de réseau:" @@ -571,6 +583,9 @@ msgstr "Vérifier BPB" msgid "CD-ROM drives:" msgstr "Lecterus CD-ROM:" +msgid "Earlier drive" +msgstr "Lecteur plus tôt" + msgid "MO drives:" msgstr "Lecteurs magnéto-optiques:" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index c39644c00..244e78304 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -244,11 +244,8 @@ msgstr "&Prazno" msgid "&Reload previous image" msgstr "&Ponovo učitaj prethodnu sliku" -msgid "&Image" -msgstr "&Slika" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Mapa..." msgid "Target &framerate" msgstr "&Ciljni broj okvira u sekundi" @@ -385,6 +382,12 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo grafika" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a grafika" + +msgid "XGA Graphics" +msgstr "XGA grafika" + msgid "Mouse:" msgstr "Miš:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Koristi FLOAT32 za zvuk" +msgid "FM synth driver" +msgstr "Drajver za FM sintisajzer" + +msgid "Nuked (more accurate)" +msgstr "Nuked (precizniji)" + +msgid "YMFM (faster)" +msgstr "YMFM (brži)" + msgid "Network type:" msgstr "Tip mreže:" @@ -571,6 +583,9 @@ msgstr "Provjeraj BPB" msgid "CD-ROM drives:" msgstr "CD-ROM pogoni:" +msgid "Earlier drive" +msgstr "Raniji pogon" + msgid "MO drives:" msgstr "MO pogoni:" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 7d3d524c9..c94e019f6 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -244,11 +244,8 @@ msgstr "&Kiadás" msgid "&Reload previous image" msgstr "Előző képfájl &újratöltése" -msgid "&Image" -msgstr "&Meglévő képfájl &megnyitása..." - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Mappa..." msgid "Target &framerate" msgstr "Cél &képkockasebesség" @@ -385,6 +382,12 @@ msgstr "Videokártya:" msgid "Voodoo Graphics" msgstr "Voodoo-gyorsítókártya" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a-gyorsítókártya" + +msgid "XGA Graphics" +msgstr "XGA-gyorsítókártya" + msgid "Mouse:" msgstr "Egér:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "FLOAT32 használata" +msgid "FM synth driver" +msgstr "FM szintetizátor meghajtó" + +msgid "Nuked (more accurate)" +msgstr "Nuked (pontosabb)" + +msgid "YMFM (faster)" +msgstr "YMFM (gyorsabb)" + msgid "Network type:" msgstr "Hálózati típusa:" @@ -571,6 +583,9 @@ msgstr "BPB ellenőrzés" msgid "CD-ROM drives:" msgstr "CD-ROM meghajtók:" +msgid "Earlier drive" +msgstr "Korábbi meghajtó" + msgid "MO drives:" msgstr "MO-meghajtók:" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index d7b2c5006..c1814eaeb 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -244,11 +244,8 @@ msgstr "&Espelli" msgid "&Reload previous image" msgstr "&Ricarica l'immagine precedente" -msgid "&Image" -msgstr "&Immagine" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Cartella..." msgid "Target &framerate" msgstr "Imposta obiettivo &fotogrammi" @@ -385,6 +382,12 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Grafica Voodoo" +msgid "IBM 8514/a Graphics" +msgstr "Grafica IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Grafica XGA" + msgid "Mouse:" msgstr "Mouse:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Usa suono FLOAT32" +msgid "FM synth driver" +msgstr "Driver sint. FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (più accurato)" + +msgid "YMFM (faster)" +msgstr "YMFM (più veloce)" + msgid "Network type:" msgstr "Tipo di rete:" @@ -571,6 +583,9 @@ msgstr "Verifica BPB" msgid "CD-ROM drives:" msgstr "Unità CD-ROM:" +msgid "Earlier drive" +msgstr "Unità anteriore" + msgid "MO drives:" msgstr "Unità magneto-ottiche:" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 790ea1ebc..71b5d921f 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -244,11 +244,8 @@ msgstr "空(&M)" msgid "&Reload previous image" msgstr "前のイメージを再読み込み(&R)" -msgid "&Image" -msgstr "イメージ(&I)" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "フォルダ(&F)..." msgid "Target &framerate" msgstr "目標フレームレート(&F)" @@ -385,6 +382,12 @@ msgstr "ビデオカード:" msgid "Voodoo Graphics" msgstr "Voodooグラフィック" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/aグラフィック" + +msgid "XGA Graphics" +msgstr "XGAグラフィック" + msgid "Mouse:" msgstr "マウス:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "FLOAT32サウンドを使用する" +msgid "FM synth driver" +msgstr "FMシンセドライバー" + +msgid "Nuked (more accurate)" +msgstr "Nuked (高精度化)" + +msgid "YMFM (faster)" +msgstr "YMFM (より速く)" + msgid "Network type:" msgstr "ネットワークタイプ:" @@ -571,6 +583,9 @@ msgstr "BPBをチェック" msgid "CD-ROM drives:" msgstr "CD-ROMドライブ:" +msgid "Earlier drive" +msgstr "アーリードライブ" + msgid "MO drives:" msgstr "光磁気ドライブ:" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 05d8dcf59..1ebabcfe4 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -244,11 +244,8 @@ msgstr "비었음(&M)" msgid "&Reload previous image" msgstr "이전 이미지 다시 불러오기(&R)" -msgid "&Image" -msgstr "이미지(&I)" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "폴더(&F)..." msgid "Target &framerate" msgstr "목표 프레임 레이트(&F)" @@ -385,6 +382,12 @@ msgstr "비디오 카드:" msgid "Voodoo Graphics" msgstr "Voodoo 그래픽" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a 그래픽" + +msgid "XGA Graphics" +msgstr "XGA 그래픽" + msgid "Mouse:" msgstr "마우스:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "FLOAT32 사운드 사용" +msgid "FM synth driver" +msgstr "FM 신디사이저 드라이버" + +msgid "Nuked (more accurate)" +msgstr "Nuked (더 정확한)" + +msgid "YMFM (faster)" +msgstr "YMFM (더 빠르게)" + msgid "Network type:" msgstr "네트워크 종류:" @@ -571,6 +583,9 @@ msgstr "BPB 확인" msgid "CD-ROM drives:" msgstr "CD-ROM 드라이브:" +msgid "Earlier drive" +msgstr "이전 드라이브" + msgid "MO drives:" msgstr "광자기 드라이브:" @@ -941,28 +956,28 @@ msgid "Cartridge images" msgstr "카트리지 이미지" msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "렌더러 초기화 오류" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) 렌더러를 초기화할 수 없습니다. 다른 렌더러를 사용하십시오." msgid "Resume execution" -msgstr "Resume execution" +msgstr "실행 재개" msgid "Pause execution" -msgstr "Pause execution" +msgstr "실행 일시 중지" msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" +msgstr "Ctrl+Alt+Del" msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" +msgstr "Ctrl+Alt+Esc" msgid "Hard reset" -msgstr "Hard reset" +msgstr "재시작" msgid "ACPI shutdown" -msgstr "ACPI shutdown" +msgstr "ACPI 종료" msgid "Hard disk (%s)" msgstr "하드 디스크 (%s)" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 71d109e2a..c0884601c 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -244,11 +244,8 @@ msgstr "P&usty" msgid "&Reload previous image" msgstr "&Przeładuj poprzedni obraz" -msgid "&Image" -msgstr "&Obraz" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Teczka..." msgid "Target &framerate" msgstr "Docelowa &liczba klatek na sekundę" @@ -385,6 +382,12 @@ msgstr "Wideo:" msgid "Voodoo Graphics" msgstr "Grafika Voodoo" +msgid "IBM 8514/a Graphics" +msgstr "Grafika IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Grafika XGA" + msgid "Mouse:" msgstr "Mysz:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Użyj dźwięku FLOAT32" +msgid "FM synth driver" +msgstr "Sterownik syntezy FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (dokładniejszy)" + +msgid "YMFM (faster)" +msgstr "YMFM (szybszy)" + msgid "Network type:" msgstr "Rodzaj sieci:" @@ -571,6 +583,9 @@ msgstr "Sprawdzaj BPB" msgid "CD-ROM drives:" msgstr "Napędy CD-ROM:" +msgid "Earlier drive" +msgstr "Wcześniejszy napęd" + msgid "MO drives:" msgstr "Napędy MO:" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 29e6031a6..d9ddcec83 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -244,9 +244,6 @@ msgstr "&Vazio" msgid "&Reload previous image" msgstr "&Recarregar imagem anterior" -msgid "&Image" -msgstr "&Imagem" - msgid "&Folder..." msgstr "&Pasta..." @@ -385,6 +382,12 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "3DFX Voodoo" +msgid "IBM 8514/a Graphics" +msgstr "Gráficos IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Gráficos XGA" + msgid "Mouse:" msgstr "Mouse:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Usar som FLOAT32" +msgid "FM synth driver" +msgstr "Controlador de sint. FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (mais preciso)" + +msgid "YMFM (faster)" +msgstr "YMFM (mais rápido)" + msgid "Network type:" msgstr "Tipo de rede:" @@ -571,6 +583,9 @@ msgstr "Verificar BPB" msgid "CD-ROM drives:" msgstr "Unidades de CD-ROM:" +msgid "Earlier drive" +msgstr "Unidade anterior" + msgid "MO drives:" msgstr "Unidades magneto-ópticas:" @@ -842,7 +857,7 @@ msgid "About 86Box" msgstr "Sobre o 86Box" msgid "86Box v" -msgstr "86Box versão " +msgstr "86Box versão" msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgstr "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 8349f7035..33501ecc7 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -244,11 +244,8 @@ msgstr "&CDROM vazio" msgid "&Reload previous image" msgstr "&Recarregar imagem anterior" -msgid "&Image" -msgstr "&Imagem" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Pasta..." msgid "Target &framerate" msgstr "&Taxa de quadros de destino" @@ -385,6 +382,12 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "Gráficos Voodoo" +msgid "IBM 8514/a Graphics" +msgstr "Gráficos IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Gráficos XGA" + msgid "Mouse:" msgstr "Rato:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Utilizar som FLOAT32" +msgid "FM synth driver" +msgstr "Controlador de sint. FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (mais exacto)" + +msgid "YMFM (faster)" +msgstr "YMFM (mais rápido)" + msgid "Network type:" msgstr "Tipo de rede:" @@ -571,6 +583,9 @@ msgstr "Verificar BPB" msgid "CD-ROM drives:" msgstr "Unidades CD-ROM:" +msgid "Earlier drive" +msgstr "Unidade anterior" + msgid "MO drives:" msgstr "Unidades magneto-ópticas:" @@ -635,7 +650,7 @@ msgid "ZIP images" msgstr "Imagens ZIP" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "O 86Box não conseguiu encontrar nenhuma imagem ROM utilizável.\n\nPor favor, vá descarregue um pacote ROM e instale-o na pasta \"roms\"." +msgstr "O 86Box não conseguiu encontrar nenhuma imagem ROM utilizável.\n\nPor favor, vá a href=\"https://github.com/86Box/roms/releases/latest\">descarregue um pacote ROM e instale-o na pasta \"roms\"." msgid "(empty)" msgstr "(empty)" @@ -941,28 +956,28 @@ msgid "Cartridge images" msgstr "Imagens de cartucho" msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "Erro na inicialização do renderizador" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Não foi possível inicializar o renderizador OpenGL (3.0 Core). Utilize outro renderizador." msgid "Resume execution" -msgstr "Resume execution" +msgstr "Retomar execução" msgid "Pause execution" -msgstr "Pause execution" +msgstr "Pausar execução" msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" +msgstr "Ctrl+Alt+Del" msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" +msgstr "Ctrl+Alt+Esc" msgid "Hard reset" -msgstr "Hard reset" +msgstr "Reinicialização completa" msgid "ACPI shutdown" -msgstr "ACPI shutdown" +msgstr "Encerramento ACPI" msgid "Hard disk (%s)" msgstr "Disco rígido (%s)" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 9e0b4101d..6cc388b58 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -244,11 +244,8 @@ msgstr "П&устой" msgid "&Reload previous image" msgstr "&Снова загрузить предыдущий образ" -msgid "&Image" -msgstr "&Образ..." - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Папка..." msgid "Target &framerate" msgstr "Целевая &частота кадров" @@ -385,6 +382,12 @@ msgstr "Видеокарта:" msgid "Voodoo Graphics" msgstr "Ускоритель Voodoo" +msgid "IBM 8514/a Graphics" +msgstr "Ускоритель IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Ускоритель XGA" + msgid "Mouse:" msgstr "Мышь:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "FLOAT32 звук" +msgid "FM synth driver" +msgstr "Драйвер FM-синтезатора" + +msgid "Nuked (more accurate)" +msgstr "Nuked (более точный)" + +msgid "YMFM (faster)" +msgstr "YMFM (быстрей)" + msgid "Network type:" msgstr "Тип сети:" @@ -571,6 +583,9 @@ msgstr "Проверять BPB" msgid "CD-ROM drives:" msgstr "Дисководы CD-ROM:" +msgid "Earlier drive" +msgstr "Предыдущий дисковод" + msgid "MO drives:" msgstr "Магнитооптические дисководы:" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 80f36a022..08060a790 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -244,11 +244,8 @@ msgstr "&Prazen" msgid "&Reload previous image" msgstr "&Naloži zadnjo sliko" -msgid "&Image" -msgstr "&Slika" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Mapa..." msgid "Target &framerate" msgstr "&Ciljno št. sličic na sekundo" @@ -385,6 +382,12 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo grafika" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a grafika" + +msgid "XGA Graphics" +msgstr "XGA grafika" + msgid "Mouse:" msgstr "Miška:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "Uporabi FLOAT32 za zvok" +msgid "FM synth driver" +msgstr "Gonilnik sintetizacije FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (točnejši)" + +msgid "YMFM (faster)" +msgstr "YMFM (hitrejši)" + msgid "Network type:" msgstr "Vrsta omrežja:" @@ -571,6 +583,9 @@ msgstr "Preverjaj BPB" msgid "CD-ROM drives:" msgstr "Pogoni CD-ROM:" +msgid "Earlier drive" +msgstr "Zgodnejši pogon" + msgid "MO drives:" msgstr "Magnetno-optični pogoni:" @@ -941,16 +956,16 @@ msgid "Cartridge images" msgstr "Slike spominskega vložka" msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "Napaka pri zagonu sistema za upodabljanje" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Sistema za upodabljanje OpenGL (3.0 Core) ni bilo mogoče zagnati. Uporabite drug sistem za upodabljanje." msgid "Resume execution" -msgstr "Resume execution" +msgstr "Nadaljuj izvajanje" msgid "Pause execution" -msgstr "Pause execution" +msgstr "Prekini izvajanje" msgid "Press Ctrl+Alt+Del" msgstr "Press Ctrl+Alt+Del" @@ -959,10 +974,10 @@ msgid "Press Ctrl+Alt+Esc" msgstr "Press Ctrl+Alt+Esc" msgid "Hard reset" -msgstr "Hard reset" +msgstr "Ponovni zagon" msgid "ACPI shutdown" -msgstr "ACPI shutdown" +msgstr "Zaustavitev ACPI" msgid "Hard disk (%s)" msgstr "Trdi disk (%s)" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index aa0273c79..5c9ddbd4f 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -244,11 +244,8 @@ msgstr "İmajı &çıkar" msgid "&Reload previous image" msgstr "&Önceki imajı seç" -msgid "&Image" -msgstr "&İmaj seç" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Klasör..." msgid "Target &framerate" msgstr "Hedef &kare oranı" @@ -385,6 +382,12 @@ msgstr "Ekran kartı:" msgid "Voodoo Graphics" msgstr "Voodoo Grafikleri" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a Grafikleri" + +msgid "XGA Graphics" +msgstr "XGA Grafikleri" + msgid "Mouse:" msgstr "Fare:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "FLOAT32 ses kullan" +msgid "FM synth driver" +msgstr "FM sentez sürücüsü" + +msgid "Nuked (more accurate)" +msgstr "Nuked (daha doğru)" + +msgid "YMFM (faster)" +msgstr "YMFM (daha hızlı)" + msgid "Network type:" msgstr "Ağ tipi:" @@ -571,6 +583,9 @@ msgstr "BPB'yi denetle" msgid "CD-ROM drives:" msgstr "CD-ROM sürücüleri:" +msgid "Earlier drive" +msgstr "Daha erken sürüş" + msgid "MO drives:" msgstr "MO sürücüleri:" @@ -941,28 +956,28 @@ msgid "Cartridge images" msgstr "Kartuş imajları" msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "Oluşturucu başlatılırken hata oluştu" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) görüntüleyici başlatılamadı. Başka bir görüntüleyici kullanın." msgid "Resume execution" -msgstr "Resume execution" +msgstr "Yürütmeye devam et" msgid "Pause execution" -msgstr "Pause execution" +msgstr "Yürütmeyi duraklat" msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" +msgstr "Ctrl+Alt+Del" msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" +msgstr "Ctrl+Alt+Esc" msgid "Hard reset" -msgstr "Hard reset" +msgstr "Makineyi yeniden başlat" msgid "ACPI shutdown" -msgstr "ACPI shutdown" +msgstr "ACPI kapatma" msgid "Hard disk (%s)" msgstr "Hard disk (%s)" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index f40e4d826..c2a839542 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -244,11 +244,8 @@ msgstr "&Пустий" msgid "&Reload previous image" msgstr "&Знову завантажити попередній образ" -msgid "&Image" -msgstr "&Образ..." - msgid "&Folder..." -msgstr "&Folder..." +msgstr "&Тека..." msgid "Target &framerate" msgstr "Цільова &частота кадрів" @@ -385,6 +382,12 @@ msgstr "Відеокарта:" msgid "Voodoo Graphics" msgstr "Прискорювач Voodoo" +msgid "IBM 8514/a Graphics" +msgstr "Прискорювач IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Прискорювач XGA" + msgid "Mouse:" msgstr "Миша:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "FLOAT32 звук" +msgid "FM synth driver" +msgstr "Драйвер FM-синтезатора" + +msgid "Nuked (more accurate)" +msgstr "Nuked (більш точний)" + +msgid "YMFM (faster)" +msgstr "YMFM (швидший)" + msgid "Network type:" msgstr "Тип мережі:" @@ -571,6 +583,9 @@ msgstr "Перевіряти BPB" msgid "CD-ROM drives:" msgstr "Дисководи CD-ROM:" +msgid "Earlier drive" +msgstr "Більш ранній дисковод" + msgid "MO drives:" msgstr "Магнітооптичні дисководи:" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index a863fc4b3..5c995ae8e 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -244,11 +244,8 @@ msgstr "空置驱动器(&M)" msgid "&Reload previous image" msgstr "载入上一个镜像(&R)" -msgid "&Image" -msgstr "镜像(&I)" - msgid "&Folder..." -msgstr "&Folder..." +msgstr "文件夹(&F)..." msgid "Target &framerate" msgstr "目标帧率(&F)" @@ -385,6 +382,12 @@ msgstr "显卡:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a Graphics" + +msgid "XGA Graphics" +msgstr "XGA Graphics" + msgid "Mouse:" msgstr "鼠标:" @@ -427,6 +430,15 @@ msgstr "Gravis Ultrasound" msgid "Use FLOAT32 sound" msgstr "使用单精度浮点 (FLOAT32)" +msgid "FM synth driver" +msgstr "调频合成器驱动器" + +msgid "Nuked (more accurate)" +msgstr "Nuked (更准确)" + +msgid "YMFM (faster)" +msgstr "YMFM (更快)" + msgid "Network type:" msgstr "网络类型:" @@ -571,6 +583,9 @@ msgstr "检查 BPB" msgid "CD-ROM drives:" msgstr "光盘驱动器:" +msgid "Earlier drive" +msgstr "早先的驱动器" + msgid "MO drives:" msgstr "磁光盘驱动器:" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po new file mode 100644 index 000000000..587db5e0c --- /dev/null +++ b/src/qt/languages/zh-TW.po @@ -0,0 +1,1221 @@ +msgid "&Action" +msgstr "動作(&A)" + +msgid "&Keyboard requires capture" +msgstr "鍵盤需要捕捉(&K)" + +msgid "&Right CTRL is left ALT" +msgstr "將右 CTRL 鍵映射為左 ALT 鍵(&R)" + +msgid "&Hard Reset..." +msgstr "硬重設(&H)..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "Ctrl+Alt+Del(&C)\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+Esc(&E)" + +msgid "&Pause" +msgstr "暫停(&P)" + +msgid "E&xit..." +msgstr "退出(&X)..." + +msgid "&View" +msgstr "檢視(&V)" + +msgid "&Hide status bar" +msgstr "隱藏狀態列(&H)" + +msgid "Hide &toolbar" +msgstr "隱藏工具列(&T)" + +msgid "&Resizeable window" +msgstr "視窗大小可調(&R)" + +msgid "R&emember size && position" +msgstr "記住視窗大小和位置(&E)" + +msgid "Re&nderer" +msgstr "渲染器(&N)" + +msgid "&SDL (Software)" +msgstr "SDL (軟體)(&S)" + +msgid "SDL (&Hardware)" +msgstr "SDL (硬體)(&H)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (OpenGL)(&O)" + +msgid "Open&GL (3.0 Core)" +msgstr "OpenGL (3.0 核心)(&G)" + +msgid "&VNC" +msgstr "VNC(&V)" + +msgid "Specify dimensions..." +msgstr "指定視窗大小..." + +msgid "F&orce 4:3 display ratio" +msgstr "強制 4:3 顯示比例(&O)" + +msgid "&Window scale factor" +msgstr "視窗縮放係數(&W)" + +msgid "&0.5x" +msgstr "0.5x(&0)" + +msgid "&1x" +msgstr "1x(&1)" + +msgid "1.&5x" +msgstr "1.5x(&5)" + +msgid "&2x" +msgstr "2x(&2)" + +msgid "&3x" +msgstr "3x(&3)" + +msgid "&4x" +msgstr "4x(&4)" + +msgid "&5x" +msgstr "5x(&5)" + +msgid "&6x" +msgstr "6x(&6)" + +msgid "&7x" +msgstr "7x(&7)" + +msgid "&8x" +msgstr "8x(&8)" + +msgid "Filter method" +msgstr "過濾方式" + +msgid "&Nearest" +msgstr "鄰近(&N)" + +msgid "&Linear" +msgstr "線性(&L)" + +msgid "Hi&DPI scaling" +msgstr "HiDPI 縮放(&D)" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "全螢幕(&F)\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "全螢幕拉伸模式(&S)" + +msgid "&Full screen stretch" +msgstr "全螢幕拉伸(&F)" + +msgid "&4:3" +msgstr "4:3(&4)" + +msgid "&Square pixels (Keep ratio)" +msgstr "保持比例(&S)" + +msgid "&Integer scale" +msgstr "整數比例(&I)" + +msgid "E&GA/(S)VGA settings" +msgstr "EGA/(S)VGA 設定(&G)" + +msgid "&Inverted VGA monitor" +msgstr "VGA 顯示器反色顯示(&I)" + +msgid "VGA screen &type" +msgstr "VGA 螢幕類型(&T)" + +msgid "RGB &Color" +msgstr "RGB 彩色(&C)" + +msgid "&RGB Grayscale" +msgstr "RGB 灰度(&R)" + +msgid "&Amber monitor" +msgstr "琥珀色單色顯示器(&A)" + +msgid "&Green monitor" +msgstr "綠色單色顯示器(&G)" + +msgid "&White monitor" +msgstr "白色單色顯示器(&W)" + +msgid "Grayscale &conversion type" +msgstr "灰度轉換類型(&C)" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT601 (NTSC/PAL)(&6)" + +msgid "BT&709 (HDTV)" +msgstr "BT709 (HDTV)(&7)" + +msgid "&Average" +msgstr "平均(&A)" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/EGA/(S)VGA 過掃描(&G)" + +msgid "Change contrast for &monochrome display" +msgstr "變更單色顯示對比度(&M)" + +msgid "&Media" +msgstr "介質(&M)" + +msgid "&Tools" +msgstr "工具(&T)" + +msgid "&Settings..." +msgstr "設定(&S)..." + +msgid "&Update status bar icons" +msgstr "更新狀態列圖示(&U)" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "擷圖(&C)\tCtrl+F11" + +msgid "&Preferences..." +msgstr "首選項(&P)..." + +msgid "Enable &Discord integration" +msgstr "啟用 Discord 整合(&D)" + +msgid "Sound &gain..." +msgstr "音量增益(&G)..." + +msgid "Begin trace\tCtrl+T" +msgstr "開始追踪\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "結束追踪\tCtrl+T" + +msgid "&Help" +msgstr "說明(&H)" + +msgid "&Documentation..." +msgstr "文件(&D)..." + +msgid "&About 86Box..." +msgstr "關於 86Box(&A)..." + +msgid "&New image..." +msgstr "新增鏡像(&N)..." + +msgid "&Existing image..." +msgstr "開啟已存在的鏡像(&E)..." + +msgid "Existing image (&Write-protected)..." +msgstr "開啟已存在的鏡像並寫保護(&W)..." + +msgid "&Record" +msgstr "錄製(&R)" + +msgid "&Play" +msgstr "播放(&P)" + +msgid "&Rewind to the beginning" +msgstr "倒帶至起點(&R)" + +msgid "&Fast forward to the end" +msgstr "快進至終點(&F)" + +msgid "E&ject" +msgstr "彈出(&J)" + +msgid "&Image..." +msgstr "鏡像(&I)..." + +msgid "E&xport to 86F..." +msgstr "匯出為 86F 格式(&x)..." + +msgid "&Mute" +msgstr "靜音(&M)" + +msgid "E&mpty" +msgstr "空置光碟機(&M)" + +msgid "&Reload previous image" +msgstr "載入上一個鏡像(&R)" + +msgid "&Folder..." +msgstr "資料夾(&F)..." + +msgid "Target &framerate" +msgstr "目標幀率(&F)" + +msgid "&Sync with video" +msgstr "與視訊同步(&S)" + +msgid "&25 fps" +msgstr "25 fps(&2)" + +msgid "&30 fps" +msgstr "30 fps(&3)" + +msgid "&50 fps" +msgstr "50 fps(&5)" + +msgid "&60 fps" +msgstr "60 fps(&6)" + +msgid "&75 fps" +msgstr "75 fps(&7)" + +msgid "&VSync" +msgstr "垂直同步(&V)" + +msgid "&Select shader..." +msgstr "選擇著色器(&S)..." + +msgid "&Remove shader" +msgstr "移除著色器(&R)" + +msgid "Preferences" +msgstr "首選項" + +msgid "Sound Gain" +msgstr "音量增益" + +msgid "New Image" +msgstr "新增鏡像" + +msgid "Settings" +msgstr "設定" + +msgid "Specify Main Window Dimensions" +msgstr "指定主視窗大小" + +msgid "OK" +msgstr "確定" + +msgid "Cancel" +msgstr "取消" + +msgid "Save these settings as &global defaults" +msgstr "將以上設定存儲為全局預設值(&G)" + +msgid "&Default" +msgstr "預設(&D)" + +msgid "Language:" +msgstr "語言:" + +msgid "Icon set:" +msgstr "圖示集:" + +msgid "Gain" +msgstr "增益" + +msgid "File name:" +msgstr "檔案名:" + +msgid "Disk size:" +msgstr "磁碟大小:" + +msgid "RPM mode:" +msgstr "轉速 (RPM) 模式:" + +msgid "Progress:" +msgstr "進度:" + +msgid "Width:" +msgstr "寬度:" + +msgid "Height:" +msgstr "高度:" + +msgid "Lock to this size" +msgstr "鎖定此大小" + +msgid "Machine type:" +msgstr "機器類型:" + +msgid "Machine:" +msgstr "機型:" + +msgid "Configure" +msgstr "配置" + +msgid "CPU type:" +msgstr "CPU 類型:" + +msgid "Speed:" +msgstr "速度:" + +msgid "FPU:" +msgstr "浮點處理器 (FPU):" + +msgid "Wait states:" +msgstr "等待狀態 (WS):" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "記憶體:" + +msgid "Time synchronization" +msgstr "時間同步" + +msgid "Disabled" +msgstr "禁用" + +msgid "Enabled (local time)" +msgstr "啟用 (本地時間)" + +msgid "Enabled (UTC)" +msgstr "啟用 (UTC)" + +msgid "Dynamic Recompiler" +msgstr "動態重編譯器" + +msgid "Video:" +msgstr "顯示卡:" + +msgid "Voodoo Graphics" +msgstr "Voodoo Graphics" + +msgid "IBM 8514/a Graphics" +msgstr "IBM 8514/a Graphics" + +msgid "XGA Graphics" +msgstr "XGA Graphics" + +msgid "Mouse:" +msgstr "滑鼠:" + +msgid "Joystick:" +msgstr "搖桿:" + +msgid "Joystick 1..." +msgstr "搖桿 1..." + +msgid "Joystick 2..." +msgstr "搖桿 2..." + +msgid "Joystick 3..." +msgstr "搖桿 3..." + +msgid "Joystick 4..." +msgstr "搖桿 4..." + +msgid "Sound card:" +msgstr "音訊卡:" + +msgid "MIDI Out Device:" +msgstr "MIDI 輸出裝置:" + +msgid "MIDI In Device:" +msgstr "MIDI 輸入裝置:" + +msgid "Standalone MPU-401" +msgstr "獨立 MPU-401" + +msgid "Innovation SSI-2001" +msgstr "Innovation SSI-2001" + +msgid "CMS / Game Blaster" +msgstr "CMS / Game Blaster" + +msgid "Gravis Ultrasound" +msgstr "Gravis Ultrasound" + +msgid "Use FLOAT32 sound" +msgstr "使用單精度浮點 (FLOAT32)" + +msgid "FM synth driver" +msgstr "調頻合成器驅動器" + +msgid "Nuked (more accurate)" +msgstr "Nuked (更準確)" + +msgid "YMFM (faster)" +msgstr "YMFM (更快)" + +msgid "Network type:" +msgstr "網路類型:" + +msgid "PCap device:" +msgstr "PCap 裝置:" + +msgid "Network adapter:" +msgstr "網路配接器:" + +msgid "COM1 Device:" +msgstr "COM1 裝置:" + +msgid "COM2 Device:" +msgstr "COM2 裝置:" + +msgid "COM3 Device:" +msgstr "COM3 裝置:" + +msgid "COM4 Device:" +msgstr "COM4 裝置:" + +msgid "LPT1 Device:" +msgstr "LPT1 裝置:" + +msgid "LPT2 Device:" +msgstr "LPT2 裝置:" + +msgid "LPT3 Device:" +msgstr "LPT3 裝置:" + +msgid "LPT4 Device:" +msgstr "LPT4 裝置:" + +msgid "Serial port 1" +msgstr "序列埠 1" + +msgid "Serial port 2" +msgstr "序列埠 2" + +msgid "Serial port 3" +msgstr "序列埠 3" + +msgid "Serial port 4" +msgstr "序列埠 4" + +msgid "Parallel port 1" +msgstr "並列埠 1" + +msgid "Parallel port 2" +msgstr "並列埠 2" + +msgid "Parallel port 3" +msgstr "並列埠 3" + +msgid "Parallel port 4" +msgstr "並列埠 4" + +msgid "HD Controller:" +msgstr "硬碟控制器:" + +msgid "FD Controller:" +msgstr "軟碟控制器:" + +msgid "Tertiary IDE Controller" +msgstr "第三 IDE 控制器" + +msgid "Quaternary IDE Controller" +msgstr "第四 IDE 控制器" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "控制器 1:" + +msgid "Controller 2:" +msgstr "控制器 2:" + +msgid "Controller 3:" +msgstr "控制器 3:" + +msgid "Controller 4:" +msgstr "控制器 4:" + +msgid "Cassette" +msgstr "磁帶" + +msgid "Hard disks:" +msgstr "硬碟:" + +msgid "&New..." +msgstr "新增(&N)..." + +msgid "&Existing..." +msgstr "已有鏡像(&E)..." + +msgid "&Remove" +msgstr "移除(&R)" + +msgid "Bus:" +msgstr "匯流排:" + +msgid "Channel:" +msgstr "通道:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "指定(&S)..." + +msgid "Sectors:" +msgstr "磁區(S):" + +msgid "Heads:" +msgstr "磁頭(H):" + +msgid "Cylinders:" +msgstr "柱面(C):" + +msgid "Size (MB):" +msgstr "大小 (MB):" + +msgid "Type:" +msgstr "類型:" + +msgid "Image Format:" +msgstr "鏡像格式:" + +msgid "Block Size:" +msgstr "塊大小:" + +msgid "Floppy drives:" +msgstr "軟碟機:" + +msgid "Turbo timings" +msgstr "加速時序" + +msgid "Check BPB" +msgstr "檢查 BPB" + +msgid "CD-ROM drives:" +msgstr "光碟機:" + +msgid "Earlier drive" +msgstr "早先的光碟機" + +msgid "MO drives:" +msgstr "磁光碟機:" + +msgid "ZIP drives:" +msgstr "ZIP 磁碟機:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA 實時時鐘:" + +msgid "ISA Memory Expansion" +msgstr "ISA 記憶體擴充" + +msgid "Card 1:" +msgstr "擴充卡 1:" + +msgid "Card 2:" +msgstr "擴充卡 2:" + +msgid "Card 3:" +msgstr "擴充卡 3:" + +msgid "Card 4:" +msgstr "擴充卡 4:" + +msgid "ISABugger device" +msgstr "ISABugger 裝置" + +msgid "POST card" +msgstr "自檢 (POST) 卡" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Microsoft JhengHei" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "錯誤" + +msgid "Fatal error" +msgstr "致命錯誤" + +msgid " - PAUSED" +msgstr " - 已暫停" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "按下 Ctrl+Alt+PgDn 返回到視窗模式。" + +msgid "Speed" +msgstr "速度" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP 鏡像" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box 找不到任何可用的 ROM 鏡像。\n\n請下載ROM 包並將其解壓到 \"roms\" 資料夾。" + +msgid "(empty)" +msgstr "(空)" + +msgid "All files" +msgstr "所有檔案" + +msgid "Turbo" +msgstr "加速" + +msgid "On" +msgstr "開" + +msgid "Off" +msgstr "關" + +msgid "All images" +msgstr "所有鏡像" + +msgid "Basic sector images" +msgstr "基本磁區鏡像" + +msgid "Surface images" +msgstr "表面鏡像" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "由於 roms/machines 資料夾中缺少合適的 ROM,機型 \"%hs\" 不可用。將切換到其他可用機型。" + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "由於 roms/video 資料夾中缺少合適的 ROM,顯示卡 \"%hs\" 不可用。將切換到其他可用顯示卡。" + +msgid "Machine" +msgstr "機型" + +msgid "Display" +msgstr "顯示" + +msgid "Input devices" +msgstr "輸入裝置" + +msgid "Sound" +msgstr "聲音" + +msgid "Network" +msgstr "網路" + +msgid "Ports (COM & LPT)" +msgstr "連接埠 (COM 和 LPT)" + +msgid "Storage controllers" +msgstr "存儲控制器" + +msgid "Hard disks" +msgstr "硬碟" + +msgid "Floppy & CD-ROM drives" +msgstr "軟碟/光碟機" + +msgid "Other removable devices" +msgstr "其他可移除裝置" + +msgid "Other peripherals" +msgstr "其他周邊裝置" + +msgid "Click to capture mouse" +msgstr "點擊視窗捕捉滑鼠" + +msgid "Press F8+F12 to release mouse" +msgstr "按下 F8+F12 釋放滑鼠" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "按下 F8+F12 或滑鼠中鍵釋放滑鼠" + +msgid "Unable to initialize FluidSynth" +msgstr "無法初始化 FluidSynth" + +msgid "Bus" +msgstr "匯流排" + +msgid "File" +msgstr "檔案" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "無法初始化視訊渲染器。" + +msgid "Default" +msgstr "預設" + +msgid "%i Wait state(s)" +msgstr "%i 等待狀態 (WS)" + +msgid "Type" +msgstr "類型" + +msgid "Failed to set up PCap" +msgstr "設定 PCap 失敗" + +msgid "No PCap devices found" +msgstr "未找到 PCap 裝置" + +msgid "Invalid PCap device" +msgstr "無效 PCap 裝置" + +msgid "Standard 2-button joystick(s)" +msgstr "標準 2 鍵搖桿" + +msgid "Standard 4-button joystick" +msgstr "標準 4 鍵搖桿" + +msgid "Standard 6-button joystick" +msgstr "標準 6 鍵搖桿" + +msgid "Standard 8-button joystick" +msgstr "標準 8 鍵搖桿" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "無" + +msgid "Unable to load keyboard accelerators." +msgstr "無法載入鍵盤加速器。" + +msgid "Unable to register raw input." +msgstr "無法註冊原始輸入。" + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "軟碟 %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "進階磁區鏡像" + +msgid "Flux images" +msgstr "Flux 鏡像" + +msgid "Unable to initialize FreeType" +msgstr "無法初始化 FreeType" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "無法初始化 SDL,需要 SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "確定要硬重設模擬器嗎?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "確定要退出 86Box 嗎?" + +msgid "Unable to initialize Ghostscript" +msgstr "無法初始化 Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "磁光碟 %i (%ls): %ls" + +msgid "MO images" +msgstr "磁光碟鏡像" + +msgid "Welcome to 86Box!" +msgstr "歡迎使用 86Box!" + +msgid "Internal controller" +msgstr "內部控制器" + +msgid "Exit" +msgstr "退出" + +msgid "No ROMs found" +msgstr "找不到 ROM" + +msgid "Do you want to save the settings?" +msgstr "要保存設定嗎?" + +msgid "This will hard reset the emulated machine." +msgstr "此操作將硬重設模擬器。" + +msgid "Save" +msgstr "保存" + +msgid "About 86Box" +msgstr "關於 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "一個舊式電腦模擬器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" + +msgid "Hardware not available" +msgstr "硬體不可用" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "請確認 libpcap 已安裝且使用相容 libpcap 的網路連線。" + +msgid "Invalid configuration" +msgstr "無效配置" + +msgid "freetype.dll" +msgstr "freetype.dll" + +msgid "libfreetype" +msgstr "libfreetype" + +msgid " is required for ESC/P printer emulation." +msgstr "ESC/P 印表機模擬需要" + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被保存為 PostScript (.ps) 檔案。" + +msgid "libfluidsynth.dll" +msgstr "libfluidsynth.dll" + +msgid "libfluidsynth" +msgstr "libfluidsynth" + +msgid " is required for FluidSynth MIDI output." +msgstr "FluidSynth MIDI 輸出需要" + +msgid "Entering fullscreen mode" +msgstr "正在進入全螢幕模式" + +msgid "Don't show this message again" +msgstr "不要再顯示此消息" + +msgid "Don't exit" +msgstr "不退出" + +msgid "Reset" +msgstr "重設" + +msgid "Don't reset" +msgstr "不重設" + +msgid "CD-ROM images" +msgstr "光碟鏡像" + +msgid "%hs Device Configuration" +msgstr "%hs 裝置配置" + +msgid "Monitor in sleep mode" +msgstr "顯示器處在睡眠狀態" + +msgid "OpenGL Shaders" +msgstr "OpenGL 著色器" + +msgid "OpenGL options" +msgstr "OpenGL 選項" + +msgid "You are loading an unsupported configuration" +msgstr "正在載入一個不受支援的配置" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "此模擬電腦禁用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" + +msgid "Continue" +msgstr "繼續" + +msgid "Cassette: %s" +msgstr "磁帶: %s" + +msgid "Cassette images" +msgstr "磁帶鏡像" + +msgid "Cartridge %i: %ls" +msgstr "卡帶 %i: %ls" + +msgid "Cartridge images" +msgstr "卡帶鏡像" + +msgid "Error initializing renderer" +msgstr "初始化渲染器時出錯" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "無法初始化 OpenGL (3.0 核心) 渲染器。請使用其他渲染器。" + +msgid "Resume execution" +msgstr "恢復執行" + +msgid "Pause execution" +msgstr "暫停執行" + +msgid "Press Ctrl+Alt+Del" +msgstr "按下 Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "按下 Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "硬重設" + +msgid "ACPI shutdown" +msgstr "ACPI 關機" + +msgid "Hard disk (%s)" +msgstr "硬碟 (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "不存在 MFM/RLL 或 ESDI CD-ROM 光碟機" + +msgid "Custom..." +msgstr "自訂..." + +msgid "Custom (large)..." +msgstr "自訂 (大容量)..." + +msgid "Add New Hard Disk" +msgstr "添加新硬碟" + +msgid "Add Existing Hard Disk" +msgstr "添加已存在的硬碟" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI 磁碟鏡像不能超過 4 GB。" + +msgid "Disk images cannot be larger than 127 GB." +msgstr "磁碟鏡像不能超過 127 GB。" + +msgid "Hard disk images" +msgstr "硬碟鏡像" + +msgid "Unable to read file" +msgstr "無法讀取檔案" + +msgid "Unable to write file" +msgstr "無法寫入檔案" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "不支援非 512 位元組磁區大小的 HDI 或 HDX 鏡像。" + +msgid "USB is not yet supported" +msgstr "尚未支援 USB" + +msgid "Disk image file already exists" +msgstr "磁碟鏡像檔案已存在" + +msgid "Please specify a valid file name." +msgstr "請指定有效的檔案名。" + +msgid "Disk image created" +msgstr "已創建磁碟鏡像" + +msgid "Make sure the file exists and is readable." +msgstr "請確定此檔案已存在並可讀取。" + +msgid "Make sure the file is being saved to a writable directory." +msgstr "請確定此檔案保存在可寫目錄中。" + +msgid "Disk image too large" +msgstr "磁碟鏡像太大" + +msgid "Remember to partition and format the newly-created drive." +msgstr "請記得為新創建的鏡像分區並格式化。" + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "選定的檔案將被覆蓋。確定繼續使用此檔案嗎?" + +msgid "Unsupported disk image" +msgstr "不支援的磁碟鏡像" + +msgid "Overwrite" +msgstr "覆蓋" + +msgid "Don't overwrite" +msgstr "不覆蓋" + +msgid "Raw image (.img)" +msgstr "原始鏡像 (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI 鏡像 (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX 鏡像 (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "固定大小 VHD (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "動態大小 VHD (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "差分 VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "大塊 (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "小塊 (512 KB)" + +msgid "VHD files" +msgstr "VHD 檔案" + +msgid "Select the parent VHD" +msgstr "選擇父 VHD 檔案" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "父映像可能在創建差異鏡像後被修改。\n\n如果鏡像檔案被移動或複製,或創建此磁碟的程式中存在錯誤,也可能發生這種情況。\n\n是否需要修復時間戳?" + +msgid "Parent and child disk timestamps do not match" +msgstr "父碟與子碟的時間戳不匹配" + +msgid "Could not fix VHD timestamp." +msgstr "無法修復 VHD 時間戳。" + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "光碟 %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (1024 簇)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (2048 簇)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128 MB (ISO 10090)" +msgstr "3.5 英寸 128 MB (ISO 10090)" + +msgid "3.5\" 230 MB (ISO 13963)" +msgstr "3.5 英寸 230 MB (ISO 13963)" + +msgid "3.5\" 540 MB (ISO 15498)" +msgstr "3.5 英寸 540 MB (ISO 15498)" + +msgid "3.5\" 640 MB (ISO 15498)" +msgstr "3.5 英寸 640 MB (ISO 15498)" + +msgid "3.5\" 1.3 GB (GigaMO)" +msgstr "3.5 英寸 1.3 GB (GigaMO)" + +msgid "3.5\" 2.3 GB (GigaMO 2)" +msgstr "3.5 英寸 2.3 GB (GigaMO 2)" + +msgid "5.25\" 600 MB" +msgstr "5.25 英寸 600 MB" + +msgid "5.25\" 650 MB" +msgstr "5.25 英寸 650 MB" + +msgid "5.25\" 1 GB" +msgstr "5.25 英寸 1 GB" + +msgid "5.25\" 1.3 GB" +msgstr "5.25 英寸 1.3 GB" + +msgid "Perfect RPM" +msgstr "標準轉速 (RPM)" + +msgid "1% below perfect RPM" +msgstr "低於標準轉速的 1%" + +msgid "1.5% below perfect RPM" +msgstr "低於標準轉速的 1.5%" + +msgid "2% below perfect RPM" +msgstr "低於標準轉速的 2%" + +msgid "(System Default)" +msgstr "(系統預設)" + diff --git a/src/qt/macos_event_filter.mm b/src/qt/macos_event_filter.mm index 0ea799f99..6f84beee5 100644 --- a/src/qt/macos_event_filter.mm +++ b/src/qt/macos_event_filter.mm @@ -1,25 +1,23 @@ #include -//#include "86box/plat.h" +// #include "86box/plat.h" #include "cocoa_mouse.hpp" #import -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/keyboard.h> #include <86box/mouse.h> #include <86box/config.h> -//#include <86box/plat.h> +// #include <86box/plat.h> #include <86box/plat_dynld.h> #include <86box/device.h> #include <86box/timer.h> #include <86box/ui.h> #include <86box/video.h> -extern int mouse_capture; +extern int mouse_capture; extern void plat_mouse_capture(int); } -typedef struct mouseinputdata -{ +typedef struct mouseinputdata { int deltax, deltay, deltaz; int mousebuttons; } mouseinputdata; @@ -28,64 +26,63 @@ static mouseinputdata mousedata; CocoaEventFilter::~CocoaEventFilter() { - } -bool CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) +bool +CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) { - if (mouse_capture) - { - if (eventType == "mac_generic_NSEvent") - { - NSEvent* event = (NSEvent*)message; + if (mouse_capture) { + if (eventType == "mac_generic_NSEvent") { + NSEvent *event = (NSEvent *) message; if ([event type] == NSEventTypeMouseMoved || [event type] == NSEventTypeLeftMouseDragged || [event type] == NSEventTypeRightMouseDragged - || [event type] == NSEventTypeOtherMouseDragged) - { + || [event type] == NSEventTypeOtherMouseDragged) { mousedata.deltax += [event deltaX]; mousedata.deltay += [event deltaY]; return true; } - if ([event type] == NSEventTypeScrollWheel) - { + if ([event type] == NSEventTypeScrollWheel) { mousedata.deltaz += [event deltaY]; return true; } - switch ([event type]) - { - default: return false; + switch ([event type]) { + default: + return false; case NSEventTypeLeftMouseDown: - { - mousedata.mousebuttons |= 1; - break; - } + { + mousedata.mousebuttons |= 1; + break; + } case NSEventTypeLeftMouseUp: - { - mousedata.mousebuttons &= ~1; - break; - } + { + mousedata.mousebuttons &= ~1; + break; + } case NSEventTypeRightMouseDown: - { - mousedata.mousebuttons |= 2; - break; - } + { + mousedata.mousebuttons |= 2; + break; + } case NSEventTypeRightMouseUp: - { - mousedata.mousebuttons &= ~2; - break; - } + { + mousedata.mousebuttons &= ~2; + break; + } case NSEventTypeOtherMouseDown: - { - mousedata.mousebuttons |= 4; - break; - } + { + mousedata.mousebuttons |= 4; + break; + } case NSEventTypeOtherMouseUp: - { - if (mouse_get_buttons() < 3) { plat_mouse_capture(0); return true; } - mousedata.mousebuttons &= ~4; - break; - } + { + if (mouse_get_buttons() < 3) { + plat_mouse_capture(0); + return true; + } + mousedata.mousebuttons &= ~4; + break; + } } return true; } @@ -93,11 +90,12 @@ bool CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *mess return false; } -extern "C" void macos_poll_mouse() +extern "C" void +macos_poll_mouse() { - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; + mouse_x = mousedata.deltax; + mouse_y = mousedata.deltay; + mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; + mouse_buttons = mousedata.mousebuttons; } diff --git a/src/qt/qt.c b/src/qt/qt.c index bb6d9658d..f1c6eee3f 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -17,7 +17,7 @@ * implemented in Qt */ #if !defined(_WIN32) || !defined(__clang__) -#include +# include #endif #include #include @@ -29,14 +29,17 @@ #include <86box/timer.h> #include <86box/nvr.h> -int qt_nvr_save(void) { +int +qt_nvr_save(void) +{ return nvr_save(); } -char icon_set[256] = ""; /* name of the iconset to be used */ +char icon_set[256] = ""; /* name of the iconset to be used */ int -plat_vidapi(char* api) { +plat_vidapi(char *api) +{ if (!strcasecmp(api, "default") || !strcasecmp(api, "system")) { return 0; } else if (!strcasecmp(api, "qt_software")) { @@ -58,34 +61,36 @@ plat_vidapi(char* api) { return 0; } -char* plat_vidapi_name(int api) { - char* name = "default"; +char * +plat_vidapi_name(int api) +{ + char *name = "default"; switch (api) { - case 0: - name = "qt_software"; - break; - case 1: - name = "qt_opengl"; - break; - case 2: - name = "qt_opengles"; - break; - case 3: - name = "qt_opengl3"; - break; - case 4: - name = "qt_vulkan"; - break; - case 5: - name = "qt_d3d9"; - break; - case 6: - name = "vnc"; - break; - default: - fatal("Unknown renderer: %i\n", api); - break; + case 0: + name = "qt_software"; + break; + case 1: + name = "qt_opengl"; + break; + case 2: + name = "qt_opengles"; + break; + case 3: + name = "qt_opengl3"; + break; + case 4: + name = "qt_vulkan"; + break; + case 5: + name = "qt_d3d9"; + break; + case 6: + name = "vnc"; + break; + default: + fatal("Unknown renderer: %i\n", api); + break; } return name; diff --git a/src/qt/qt_cdrom.c b/src/qt/qt_cdrom.c index a15e9c600..d0ab0113e 100644 --- a/src/qt/qt_cdrom.c +++ b/src/qt/qt_cdrom.c @@ -45,11 +45,11 @@ plat_cdrom_ui_update(uint8_t id, uint8_t reload) cdrom_t *drv = &cdrom[id]; if (drv->host_drive == 0) { - ui_sb_update_icon_state(SB_CDROM|id, 1); + ui_sb_update_icon_state(SB_CDROM | id, 1); } else { - ui_sb_update_icon_state(SB_CDROM|id, 0); + ui_sb_update_icon_state(SB_CDROM | id, 0); } - //media_menu_update_cdrom(id); - ui_sb_update_tip(SB_CDROM|id); + // media_menu_update_cdrom(id); + ui_sb_update_tip(SB_CDROM | id); } diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index b4269d2e7..fed8e72b3 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -3,14 +3,14 @@ #include #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/video.h> } D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index) - : QWidget{parent}, RendererCommon() + : QWidget { parent } + , RendererCommon() { QPalette pal = palette(); pal.setColor(QPalette::Window, Qt::black); @@ -22,7 +22,7 @@ D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index) setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_OpaquePaintEvent); - windowHandle = (HWND)winId(); + windowHandle = (HWND) winId(); surfaceInUse = true; RendererCommon::parentWidget = parent; @@ -36,24 +36,36 @@ D3D9Renderer::~D3D9Renderer() finalize(); } -void D3D9Renderer::finalize() +void +D3D9Renderer::finalize() { if (!finalized) { - while (surfaceInUse) {} + while (surfaceInUse) { } finalized = true; } surfaceInUse = true; - if (d3d9surface) { d3d9surface->Release(); d3d9surface = nullptr;} - if (d3d9dev) { d3d9dev->Release(); d3d9dev = nullptr; } - if (d3d9) { d3d9->Release(); d3d9 = nullptr; }; + if (d3d9surface) { + d3d9surface->Release(); + d3d9surface = nullptr; + } + if (d3d9dev) { + d3d9dev->Release(); + d3d9dev = nullptr; + } + if (d3d9) { + d3d9->Release(); + d3d9 = nullptr; + }; } -void D3D9Renderer::hideEvent(QHideEvent *event) +void +D3D9Renderer::hideEvent(QHideEvent *event) { finalize(); } -void D3D9Renderer::showEvent(QShowEvent *event) +void +D3D9Renderer::showEvent(QShowEvent *event) { params = {}; @@ -71,13 +83,15 @@ void D3D9Renderer::showEvent(QShowEvent *event) params.hDeviceWindow = windowHandle; HRESULT result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); - if (FAILED(result)) result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); + if (FAILED(result)) + result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); if (FAILED(result)) { return error("Failed to create Direct3D 9 device"); } result = d3d9dev->CreateOffscreenPlainSurface(2048, 2048, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); - if (FAILED(result)) result = d3d9dev->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); + if (FAILED(result)) + result = d3d9dev->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); if (FAILED(result)) { return error("Failed to create Direct3D 9 surface"); } @@ -86,33 +100,34 @@ void D3D9Renderer::showEvent(QShowEvent *event) alreadyInitialized = true; } surfaceInUse = false; - finalized = false; + finalized = false; } -void D3D9Renderer::paintEvent(QPaintEvent *event) +void +D3D9Renderer::paintEvent(QPaintEvent *event) { - IDirect3DSurface9* backbuffer = nullptr; - RECT srcRect, dstRect; - HRESULT result = d3d9dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); + IDirect3DSurface9 *backbuffer = nullptr; + RECT srcRect, dstRect; + HRESULT result = d3d9dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); if (FAILED(result)) { return; } - srcRect.top = source.top(); + srcRect.top = source.top(); srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); - dstRect.top = destination.top(); + srcRect.left = source.left(); + srcRect.right = source.right(); + dstRect.top = destination.top(); dstRect.bottom = destination.bottom(); - dstRect.left = destination.left(); - dstRect.right = destination.right(); + dstRect.left = destination.left(); + dstRect.right = destination.right(); d3d9dev->BeginScene(); d3d9dev->Clear(0, nullptr, D3DCLEAR_TARGET, 0xFF000000, 0, 0); - while (surfaceInUse) {} + while (surfaceInUse) { } surfaceInUse = true; d3d9dev->StretchRect(d3d9surface, &srcRect, backbuffer, &dstRect, video_filter_method == 0 ? D3DTEXF_POINT : D3DTEXF_LINEAR); - result = d3d9dev->EndScene(); + result = d3d9dev->EndScene(); surfaceInUse = false; if (SUCCEEDED(result)) { if (FAILED(d3d9dev->PresentEx(nullptr, nullptr, 0, nullptr, 0))) { @@ -122,51 +137,57 @@ void D3D9Renderer::paintEvent(QPaintEvent *event) } } -bool D3D9Renderer::event(QEvent *event) +bool +D3D9Renderer::event(QEvent *event) { bool res = false; - if (!eventDelegate(event, res)) return QWidget::event(event); + if (!eventDelegate(event, res)) + return QWidget::event(event); return res; } -void D3D9Renderer::resizeEvent(QResizeEvent *event) +void +D3D9Renderer::resizeEvent(QResizeEvent *event) { onResize(event->size().width() * devicePixelRatioF(), event->size().height() * devicePixelRatioF()); - params.BackBufferWidth = event->size().width() * devicePixelRatioF(); + params.BackBufferWidth = event->size().width() * devicePixelRatioF(); params.BackBufferHeight = event->size().height() * devicePixelRatioF(); - if (d3d9dev) d3d9dev->Reset(¶ms); + if (d3d9dev) + d3d9dev->Reset(¶ms); QWidget::resizeEvent(event); } -void D3D9Renderer::blit(int x, int y, int w, int h) +void +D3D9Renderer::blit(int x, int y, int w, int h) { if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) { video_blit_complete_monitor(m_monitor_index); return; } - surfaceInUse = true; + surfaceInUse = true; auto origSource = source; source.setRect(x, y, w, h); - RECT srcRect; + RECT srcRect; D3DLOCKED_RECT lockRect; - srcRect.top = source.top(); + srcRect.top = source.top(); srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); + srcRect.left = source.left(); + srcRect.right = source.right(); if (monitors[m_monitor_index].mon_screenshots) { video_screenshot_monitor((uint32_t *) &(monitors[m_monitor_index].target_buffer->line[y][x]), 0, 0, 2048, m_monitor_index); } if (SUCCEEDED(d3d9surface->LockRect(&lockRect, &srcRect, 0))) { for (int y1 = 0; y1 < h; y1++) { - video_copy(((uint8_t*)lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4); + video_copy(((uint8_t *) lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4); } video_blit_complete_monitor(m_monitor_index); d3d9surface->UnlockRect(); - } - else video_blit_complete_monitor(m_monitor_index); - if (origSource != source) onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF()); + } else + video_blit_complete_monitor(m_monitor_index); + if (origSource != source) + onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF()); surfaceInUse = false; QTimer::singleShot(0, this, [this] { this->update(); }); } diff --git a/src/qt/qt_d3d9renderer.hpp b/src/qt/qt_d3d9renderer.hpp index d93781236..2ec7b0327 100644 --- a/src/qt/qt_d3d9renderer.hpp +++ b/src/qt/qt_d3d9renderer.hpp @@ -8,8 +8,7 @@ #include #include -class D3D9Renderer : public QWidget, public RendererCommon -{ +class D3D9Renderer : public QWidget, public RendererCommon { Q_OBJECT public: explicit D3D9Renderer(QWidget *parent = nullptr, int monitor_index = 0); @@ -19,27 +18,27 @@ public: void finalize() override; protected: - void showEvent(QShowEvent* event) override; - void hideEvent(QHideEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void paintEvent(QPaintEvent *event) override; - bool event(QEvent* event) override; - QPaintEngine* paintEngine() const override { return nullptr; } + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void paintEvent(QPaintEvent *event) override; + bool event(QEvent *event) override; + QPaintEngine *paintEngine() const override { return nullptr; } signals: void initialized(); void error(QString); private: - HWND windowHandle = 0; - D3DPRESENT_PARAMETERS params{}; - IDirect3D9Ex* d3d9 = nullptr; - IDirect3DDevice9Ex* d3d9dev = nullptr; - IDirect3DSurface9* d3d9surface = nullptr; + HWND windowHandle = 0; + D3DPRESENT_PARAMETERS params {}; + IDirect3D9Ex *d3d9 = nullptr; + IDirect3DDevice9Ex *d3d9dev = nullptr; + IDirect3DSurface9 *d3d9surface = nullptr; - std::atomic surfaceInUse{false}, finalized{false}; - bool alreadyInitialized = false; - int m_monitor_index = 0; + std::atomic surfaceInUse { false }, finalized { false }; + bool alreadyInitialized = false; + int m_monitor_index = 0; }; #endif // D3D9RENDERER_HPP diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index 390a5ab10..81f8b8493 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -39,9 +39,9 @@ extern "C" { #include "qt_filefield.hpp" #include "qt_models_common.hpp" -DeviceConfig::DeviceConfig(QWidget *parent) : - QDialog(parent), - ui(new Ui::DeviceConfig) +DeviceConfig::DeviceConfig(QWidget *parent) + : QDialog(parent) + , ui(new Ui::DeviceConfig) { ui->setupUi(this); } @@ -51,7 +51,9 @@ DeviceConfig::~DeviceConfig() delete ui; } -void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Settings* settings) { +void +DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *settings) +{ DeviceConfig dc(settings); dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); int c, d, p, q; @@ -59,142 +61,142 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting device_context_t device_context; device_set_context(&device_context, device, instance); - const auto* config = device->config; + const auto *config = device->config; while (config->type != -1) { switch (config->type) { - case CONFIG_BINARY: - { - auto value = config_get_int(device_context.name, const_cast(config->name), config->default_int); - auto* cbox = new QCheckBox(); - cbox->setObjectName(config->name); - cbox->setChecked(value > 0); - dc.ui->formLayout->addRow(config->description, cbox); - break; - } + case CONFIG_BINARY: + { + auto value = config_get_int(device_context.name, const_cast(config->name), config->default_int); + auto *cbox = new QCheckBox(); + cbox->setObjectName(config->name); + cbox->setChecked(value > 0); + dc.ui->formLayout->addRow(config->description, cbox); + break; + } #ifdef USE_RTMIDI - case CONFIG_MIDI_OUT: - { - auto* cbox = new QComboBox(); - cbox->setObjectName(config->name); - auto* model = cbox->model(); - int currentIndex = -1; - int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_out_get_dev_name(i, midiName); + case CONFIG_MIDI_OUT: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto *model = cbox->model(); + int currentIndex = -1; + int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); + for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_out_get_dev_name(i, midiName); - Models::AddEntry(model, midiName, i); - if (selected == i) { - currentIndex = i; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } - case CONFIG_MIDI_IN: - { - auto* cbox = new QComboBox(); - cbox->setObjectName(config->name); - auto* model = cbox->model(); - int currentIndex = -1; - int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_in_get_dev_name(i, midiName); - - Models::AddEntry(model, midiName, i); - if (selected == i) { - currentIndex = i; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } -#endif - case CONFIG_SELECTION: - case CONFIG_HEX16: - case CONFIG_HEX20: - { - auto* cbox = new QComboBox(); - cbox->setObjectName(config->name); - auto* model = cbox->model(); - int currentIndex = -1; - int selected = 0; - switch (config->type) { - case CONFIG_SELECTION: - selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - break; - case CONFIG_HEX16: - selected = config_get_hex16(device_context.name, const_cast(config->name), config->default_int); - break; - case CONFIG_HEX20: - selected = config_get_hex20(device_context.name, const_cast(config->name), config->default_int); - break; - } - - for (auto* sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && (strlen(sel->description) > 0); ++sel) { - int row = Models::AddEntry(model, sel->description, sel->value); - if (selected == sel->value) { - currentIndex = row; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } - case CONFIG_BIOS: - { - auto* cbox = new QComboBox(); - cbox->setObjectName(config->name); - auto* model = cbox->model(); - int currentIndex = -1; - char *selected; - selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); - - c = q = 0; - for (auto* bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && (strlen(bios->name) > 0); ++bios) { - p = 0; - for (d = 0; d < bios->files_no; d++) - p += !!rom_present(const_cast(bios->files[d])); - if (p == bios->files_no) { - int row = Models::AddEntry(model, bios->name, q); - if (!strcmp(selected, bios->internal_name)) { - currentIndex = row; + Models::AddEntry(model, midiName, i); + if (selected == i) { + currentIndex = i; + } } - c++; - } - q++; - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } - case CONFIG_SPINNER: - { - int value = config_get_int(device_context.name, const_cast(config->name), config->default_int); - auto* spinBox = new QSpinBox(); - spinBox->setObjectName(config->name); - spinBox->setMaximum(config->spinner.max); - spinBox->setMinimum(config->spinner.min); - if (config->spinner.step > 0) { - spinBox->setSingleStep(config->spinner.step); - } - spinBox->setValue(value); - dc.ui->formLayout->addRow(config->description, spinBox); - break; - } - case CONFIG_FNAME: - { - auto* fileName = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); - auto* fileField = new FileField(); - fileField->setObjectName(config->name); - fileField->setFileName(fileName); - fileField->setFilter(QString(config->file_filter).left(strcspn(config->file_filter, "|"))); - dc.ui->formLayout->addRow(config->description, fileField); - break; - } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_MIDI_IN: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto *model = cbox->model(); + int currentIndex = -1; + int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); + for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_in_get_dev_name(i, midiName); + + Models::AddEntry(model, midiName, i); + if (selected == i) { + currentIndex = i; + } + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } +#endif + case CONFIG_SELECTION: + case CONFIG_HEX16: + case CONFIG_HEX20: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto *model = cbox->model(); + int currentIndex = -1; + int selected = 0; + switch (config->type) { + case CONFIG_SELECTION: + selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); + break; + case CONFIG_HEX16: + selected = config_get_hex16(device_context.name, const_cast(config->name), config->default_int); + break; + case CONFIG_HEX20: + selected = config_get_hex20(device_context.name, const_cast(config->name), config->default_int); + break; + } + + for (auto *sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && (strlen(sel->description) > 0); ++sel) { + int row = Models::AddEntry(model, sel->description, sel->value); + if (selected == sel->value) { + currentIndex = row; + } + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_BIOS: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto *model = cbox->model(); + int currentIndex = -1; + char *selected; + selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); + + c = q = 0; + for (auto *bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && (strlen(bios->name) > 0); ++bios) { + p = 0; + for (d = 0; d < bios->files_no; d++) + p += !!rom_present(const_cast(bios->files[d])); + if (p == bios->files_no) { + int row = Models::AddEntry(model, bios->name, q); + if (!strcmp(selected, bios->internal_name)) { + currentIndex = row; + } + c++; + } + q++; + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_SPINNER: + { + int value = config_get_int(device_context.name, const_cast(config->name), config->default_int); + auto *spinBox = new QSpinBox(); + spinBox->setObjectName(config->name); + spinBox->setMaximum(config->spinner.max); + spinBox->setMinimum(config->spinner.min); + if (config->spinner.step > 0) { + spinBox->setSingleStep(config->spinner.step); + } + spinBox->setValue(value); + dc.ui->formLayout->addRow(config->description, spinBox); + break; + } + case CONFIG_FNAME: + { + auto *fileName = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); + auto *fileField = new FileField(); + fileField->setObjectName(config->name); + fileField->setFileName(fileName); + fileField->setFilter(QString(config->file_filter).left(strcspn(config->file_filter, "|"))); + dc.ui->formLayout->addRow(config->description, fileField); + break; + } } ++config; } @@ -205,59 +207,61 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting config = device->config; while (config->type != -1) { switch (config->type) { - case CONFIG_BINARY: - { - auto* cbox = dc.findChild(config->name); - config_set_int(device_context.name, const_cast(config->name), cbox->isChecked() ? 1 : 0); - break; - } - case CONFIG_MIDI_OUT: - case CONFIG_MIDI_IN: - case CONFIG_SELECTION: - { - auto* cbox = dc.findChild(config->name); - config_set_int(device_context.name, const_cast(config->name), cbox->currentData().toInt()); - break; - } - case CONFIG_BIOS: - { - auto* cbox = dc.findChild(config->name); - int idx = cbox->currentData().toInt(); - config_set_string(device_context.name, const_cast(config->name), const_cast(config->bios[idx].internal_name)); - break; - } - case CONFIG_HEX16: - { - auto* cbox = dc.findChild(config->name); - config_set_hex16(device_context.name, const_cast(config->name), cbox->currentData().toInt()); - break; - } - case CONFIG_HEX20: - { - auto* cbox = dc.findChild(config->name); - config_set_hex20(device_context.name, const_cast(config->name), cbox->currentData().toInt()); - break; - } - case CONFIG_FNAME: - { - auto* fbox = dc.findChild(config->name); - auto fileName = fbox->fileName().toUtf8(); - config_set_string(device_context.name, const_cast(config->name), fileName.data()); - break; - } - case CONFIG_SPINNER: - { - auto* spinBox = dc.findChild(config->name); - config_set_int(device_context.name, const_cast(config->name), spinBox->value()); - break; - } + case CONFIG_BINARY: + { + auto *cbox = dc.findChild(config->name); + config_set_int(device_context.name, const_cast(config->name), cbox->isChecked() ? 1 : 0); + break; + } + case CONFIG_MIDI_OUT: + case CONFIG_MIDI_IN: + case CONFIG_SELECTION: + { + auto *cbox = dc.findChild(config->name); + config_set_int(device_context.name, const_cast(config->name), cbox->currentData().toInt()); + break; + } + case CONFIG_BIOS: + { + auto *cbox = dc.findChild(config->name); + int idx = cbox->currentData().toInt(); + config_set_string(device_context.name, const_cast(config->name), const_cast(config->bios[idx].internal_name)); + break; + } + case CONFIG_HEX16: + { + auto *cbox = dc.findChild(config->name); + config_set_hex16(device_context.name, const_cast(config->name), cbox->currentData().toInt()); + break; + } + case CONFIG_HEX20: + { + auto *cbox = dc.findChild(config->name); + config_set_hex20(device_context.name, const_cast(config->name), cbox->currentData().toInt()); + break; + } + case CONFIG_FNAME: + { + auto *fbox = dc.findChild(config->name); + auto fileName = fbox->fileName().toUtf8(); + config_set_string(device_context.name, const_cast(config->name), fileName.data()); + break; + } + case CONFIG_SPINNER: + { + auto *spinBox = dc.findChild(config->name); + config_set_int(device_context.name, const_cast(config->name), spinBox->value()); + break; + } } config++; } } } -QString DeviceConfig::DeviceName(const _device_* device, const char *internalName, int bus) { +QString +DeviceConfig::DeviceName(const _device_ *device, const char *internalName, int bus) +{ if (QStringLiteral("none") == internalName) { return tr("None"); } else if (QStringLiteral("internal") == internalName) { diff --git a/src/qt/qt_deviceconfig.hpp b/src/qt/qt_deviceconfig.hpp index 2662df11c..1ed24d618 100644 --- a/src/qt/qt_deviceconfig.hpp +++ b/src/qt/qt_deviceconfig.hpp @@ -15,16 +15,16 @@ class DeviceConfig; class Settings; -class DeviceConfig : public QDialog -{ +class DeviceConfig : public QDialog { Q_OBJECT public: explicit DeviceConfig(QWidget *parent = nullptr); ~DeviceConfig(); - static void ConfigureDevice(const _device_* device, int instance = 0, Settings* settings = nullptr); - static QString DeviceName(const _device_* device, const char* internalName, int bus); + static void ConfigureDevice(const _device_ *device, int instance = 0, Settings *settings = nullptr); + static QString DeviceName(const _device_ *device, const char *internalName, int bus); + private: Ui::DeviceConfig *ui; }; diff --git a/src/qt/qt_filefield.cpp b/src/qt/qt_filefield.cpp index 0639ad0fc..969d5ff29 100644 --- a/src/qt/qt_filefield.cpp +++ b/src/qt/qt_filefield.cpp @@ -21,13 +21,13 @@ #include -FileField::FileField(QWidget *parent) : - QWidget(parent), - ui(new Ui::FileField) +FileField::FileField(QWidget *parent) + : QWidget(parent) + , ui(new Ui::FileField) { ui->setupUi(this); - connect(ui->label, &QLineEdit::editingFinished, this, [this] () { + connect(ui->label, &QLineEdit::editingFinished, this, [this]() { fileName_ = ui->label->text(); emit fileSelected(ui->label->text()); }); @@ -39,12 +39,16 @@ FileField::~FileField() delete ui; } -void FileField::setFileName(const QString &fileName) { +void +FileField::setFileName(const QString &fileName) +{ fileName_ = fileName; ui->label->setText(fileName); } -void FileField::on_pushButton_clicked() { +void +FileField::on_pushButton_clicked() +{ QString fileName; if (createFile_) { fileName = QFileDialog::getSaveFileName(this, QString(), QString(), filter_, &selectedFilter_); diff --git a/src/qt/qt_filefield.hpp b/src/qt/qt_filefield.hpp index 00c4a5e12..8520e3e57 100644 --- a/src/qt/qt_filefield.hpp +++ b/src/qt/qt_filefield.hpp @@ -7,8 +7,7 @@ namespace Ui { class FileField; } -class FileField : public QWidget -{ +class FileField : public QWidget { Q_OBJECT public: @@ -16,26 +15,26 @@ public: ~FileField(); QString fileName() const { return fileName_; } - void setFileName(const QString& fileName); + void setFileName(const QString &fileName); - void setFilter(const QString& filter) { filter_ = filter; } + void setFilter(const QString &filter) { filter_ = filter; } QString selectedFilter() const { return selectedFilter_; } void setCreateFile(bool createFile) { createFile_ = createFile; } bool createFile() { return createFile_; } signals: - void fileSelected(const QString& fileName); + void fileSelected(const QString &fileName); private slots: void on_pushButton_clicked(); private: Ui::FileField *ui; - QString fileName_; - QString selectedFilter_; - QString filter_; - bool createFile_ = false; + QString fileName_; + QString selectedFilter_; + QString filter_; + bool createFile_ = false; }; #endif // QT_FILEFIELD_HPP diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index c5ced345f..89de664d8 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -45,9 +45,9 @@ extern "C" { #include "qt_models_common.hpp" #include "qt_util.hpp" -HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) : - QDialog(parent), - ui(new Ui::HarddiskDialog) +HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) + : QDialog(parent) + , ui(new Ui::HarddiskDialog) { ui->setupUi(this); @@ -86,7 +86,7 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) : }); } - auto* model = ui->comboBoxFormat->model(); + auto *model = ui->comboBoxFormat->model(); model->insertRows(0, 6); model->setData(model->index(0, 0), tr("Raw image (.img)")); model->setData(model->index(1, 0), tr("HDI image (.hdi)")); @@ -108,9 +108,9 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) : model = ui->comboBoxType->model(); for (int i = 0; i < 127; i++) { - uint64_t size = ((uint64_t) hdd_table[i][0]) * hdd_table[i][1] * hdd_table[i][2]; + uint64_t size = ((uint64_t) hdd_table[i][0]) * hdd_table[i][1] * hdd_table[i][2]; uint32_t size_mb = size >> 11LL; - //QString text = QString("%1 MiB (CHS: %2, %3, %4)").arg(size_mb).arg(hdd_table[i][0]).arg(hdd_table[i][1]).arg(hdd_table[i][2]); + // QString text = QString("%1 MiB (CHS: %2, %3, %4)").arg(size_mb).arg(hdd_table[i][0]).arg(hdd_table[i][1]).arg(hdd_table[i][2]); QString text = QString::asprintf(tr("%u MB (CHS: %i, %i, %i)").toUtf8().constData(), (size_mb), (hdd_table[i][0]), (hdd_table[i][1]), (hdd_table[i][2])); Models::AddEntry(model, text, i); } @@ -126,23 +126,33 @@ HarddiskDialog::~HarddiskDialog() delete ui; } -uint8_t HarddiskDialog::bus() const { +uint8_t +HarddiskDialog::bus() const +{ return static_cast(ui->comboBoxBus->currentData().toUInt()); } -uint8_t HarddiskDialog::channel() const { +uint8_t +HarddiskDialog::channel() const +{ return static_cast(ui->comboBoxChannel->currentData().toUInt()); } -QString HarddiskDialog::fileName() const { +QString +HarddiskDialog::fileName() const +{ return ui->fileField->fileName(); } -uint32_t HarddiskDialog::speed() const { +uint32_t +HarddiskDialog::speed() const +{ return static_cast(ui->comboBoxSpeed->currentData().toUInt()); } -void HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) { +void +HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) +{ bool enabled; if (index == 5) { /* They switched to a diff VHD; disable the geometry fields. */ enabled = false; @@ -177,12 +187,13 @@ void HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) { * of about 21 MB, and should only be necessary for VHDs larger than 31.5 GB, so should never be more * than a tenth of a percent change in size. */ -static void adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) +static void +adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) { if (_86box_geometry->cyl <= 65535) { - vhd_geometry->cyl = _86box_geometry->cyl; + vhd_geometry->cyl = _86box_geometry->cyl; vhd_geometry->heads = _86box_geometry->heads; - vhd_geometry->spt = _86box_geometry->spt; + vhd_geometry->spt = _86box_geometry->spt; return; } @@ -194,33 +205,35 @@ static void adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *v if (remainder > 0) desired_sectors += (85680 - remainder); - _86box_geometry->cyl = desired_sectors / (16 * 63); + _86box_geometry->cyl = desired_sectors / (16 * 63); _86box_geometry->heads = 16; - _86box_geometry->spt = 63; + _86box_geometry->spt = 63; - vhd_geometry->cyl = desired_sectors / (16 * 255); + vhd_geometry->cyl = desired_sectors / (16 * 255); vhd_geometry->heads = 16; - vhd_geometry->spt = 255; + vhd_geometry->spt = 255; } -static HarddiskDialog* callbackPtr = nullptr; -static MVHDGeom create_drive_vhd_fixed(const QString& fileName, HarddiskDialog* p, uint16_t cyl, uint8_t heads, uint8_t spt) { +static HarddiskDialog *callbackPtr = nullptr; +static MVHDGeom +create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, uint8_t heads, uint8_t spt) +{ MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; MVHDGeom vhd_geometry; adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); - int vhd_error = 0; + int vhd_error = 0; QByteArray filenameBytes = fileName.toUtf8(); - callbackPtr = p; - MVHDMeta *vhd = mvhd_create_fixed(filenameBytes.data(), vhd_geometry, &vhd_error, [](uint32_t current_sector, uint32_t total_sectors) { + callbackPtr = p; + MVHDMeta *vhd = mvhd_create_fixed(filenameBytes.data(), vhd_geometry, &vhd_error, [](uint32_t current_sector, uint32_t total_sectors) { callbackPtr->fileProgress((current_sector * 100) / total_sectors); }); - callbackPtr = nullptr; + callbackPtr = nullptr; if (vhd == NULL) { - _86box_geometry.cyl = 0; + _86box_geometry.cyl = 0; _86box_geometry.heads = 0; - _86box_geometry.spt = 0; + _86box_geometry.spt = 0; } else { mvhd_close(vhd); } @@ -228,24 +241,26 @@ static MVHDGeom create_drive_vhd_fixed(const QString& fileName, HarddiskDialog* return _86box_geometry; } -static MVHDGeom create_drive_vhd_dynamic(const QString& fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize) { +static MVHDGeom +create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize) +{ MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; MVHDGeom vhd_geometry; adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); - int vhd_error = 0; - QByteArray filenameBytes = fileName.toUtf8(); + int vhd_error = 0; + QByteArray filenameBytes = fileName.toUtf8(); MVHDCreationOptions options; options.block_size_in_sectors = blocksize; - options.path = filenameBytes.data(); - options.size_in_bytes = 0; - options.geometry = vhd_geometry; - options.type = MVHD_TYPE_DYNAMIC; + options.path = filenameBytes.data(); + options.size_in_bytes = 0; + options.geometry = vhd_geometry; + options.type = MVHD_TYPE_DYNAMIC; MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); if (vhd == NULL) { - _86box_geometry.cyl = 0; + _86box_geometry.cyl = 0; _86box_geometry.heads = 0; - _86box_geometry.spt = 0; + _86box_geometry.spt = 0; } else { mvhd_close(vhd); } @@ -253,29 +268,31 @@ static MVHDGeom create_drive_vhd_dynamic(const QString& fileName, uint16_t cyl, return _86box_geometry; } -static MVHDGeom create_drive_vhd_diff(const QString& fileName, const QString& parentFileName, int blocksize) { - int vhd_error = 0; - QByteArray filenameBytes = fileName.toUtf8(); - QByteArray parentFilenameBytes = parentFileName.toUtf8(); +static MVHDGeom +create_drive_vhd_diff(const QString &fileName, const QString &parentFileName, int blocksize) +{ + int vhd_error = 0; + QByteArray filenameBytes = fileName.toUtf8(); + QByteArray parentFilenameBytes = parentFileName.toUtf8(); MVHDCreationOptions options; options.block_size_in_sectors = blocksize; - options.path = filenameBytes.data(); - options.parent_path = parentFilenameBytes.data(); - options.type = MVHD_TYPE_DIFF; + options.path = filenameBytes.data(); + options.parent_path = parentFilenameBytes.data(); + options.type = MVHD_TYPE_DIFF; MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - MVHDGeom vhd_geometry; + MVHDGeom vhd_geometry; if (vhd == NULL) { - vhd_geometry.cyl = 0; + vhd_geometry.cyl = 0; vhd_geometry.heads = 0; - vhd_geometry.spt = 0; + vhd_geometry.spt = 0; } else { vhd_geometry = mvhd_get_geometry(vhd); if (vhd_geometry.spt > 63) { - vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); + vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); vhd_geometry.heads = 16; - vhd_geometry.spt = 63; + vhd_geometry.spt = 63; } mvhd_close(vhd); @@ -284,56 +301,61 @@ static MVHDGeom create_drive_vhd_diff(const QString& fileName, const QString& pa return vhd_geometry; } -void HarddiskDialog::onCreateNewFile() { +void +HarddiskDialog::onCreateNewFile() +{ - for (auto& curObject : children()) - { - if (qobject_cast(curObject)) qobject_cast(curObject)->setDisabled(true); + for (auto &curObject : children()) { + if (qobject_cast(curObject)) + qobject_cast(curObject)->setDisabled(true); } ui->progressBar->setEnabled(true); setResult(QDialog::Rejected); - qint64 size = ui->lineEditSize->text().toUInt() << 20U; + quint64 size = ui->lineEditSize->text().toULongLong() << 20U; if (size > 0x1FFFFFFE00ll) { QMessageBox::critical(this, tr("Disk image too large"), tr("Disk images cannot be larger than 127 GB.")); return; } - int img_format = ui->comboBoxFormat->currentIndex(); - uint32_t zero = 0; - uint32_t base = 0x1000; + int img_format = ui->comboBoxFormat->currentIndex(); + uint32_t zero = 0; + uint32_t base = 0x1000; uint32_t sector_size = 512; - auto fileName = ui->fileField->fileName(); + auto fileName = ui->fileField->fileName(); QString expectedSuffix; switch (img_format) { - case 1: - expectedSuffix = "hdi"; - break; - case 2: - expectedSuffix = "hdx"; - break; - case 3: - case 4: - case 5: - expectedSuffix = "vhd"; - break; + case IMG_FMT_HDI: + expectedSuffix = "hdi"; + break; + case IMG_FMT_HDX: + expectedSuffix = "hdx"; + break; + case IMG_FMT_VHD_FIXED: + case IMG_FMT_VHD_DYNAMIC: + case IMG_FMT_VHD_DIFF: + expectedSuffix = "vhd"; + break; } - if (! expectedSuffix.isEmpty()) { + if (!expectedSuffix.isEmpty()) { QFileInfo fileInfo(fileName); if (fileInfo.suffix().compare(expectedSuffix, Qt::CaseInsensitive) != 0) { fileName = QString("%1.%2").arg(fileName, expectedSuffix); ui->fileField->setFileName(fileName); } } + QFileInfo fi(fileName); + fileName = (fi.isRelative() && !fi.filePath().isEmpty()) ? usr_path + fi.filePath() : fi.filePath(); + ui->fileField->setFileName(fileName); QFile file(fileName); - if (! file.open(QIODevice::WriteOnly)) { + if (!file.open(QIODevice::WriteOnly)) { QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory.")); return; } - if (img_format == 1) { /* HDI file */ + if (img_format == IMG_FMT_HDI) { /* HDI file */ QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); if (size >= 0x100000000ll) { @@ -341,73 +363,66 @@ void HarddiskDialog::onCreateNewFile() { return; } uint32_t s = static_cast(size); - stream << zero; /* 00000000: Zero/unknown */ - stream << zero; /* 00000004: Zero/unknown */ - stream << base; /* 00000008: Offset at which data starts */ - stream << s; /* 0000000C: Full size of the data (32-bit) */ - stream << sector_size; /* 00000010: Sector size in bytes */ - stream << sectors_; /* 00000014: Sectors per cylinder */ - stream << heads_; /* 00000018: Heads per cylinder */ - stream << cylinders_; /* 0000001C: Cylinders */ + stream << zero; /* 00000000: Zero/unknown */ + stream << zero; /* 00000004: Zero/unknown */ + stream << base; /* 00000008: Offset at which data starts */ + stream << s; /* 0000000C: Full size of the data (32-bit) */ + stream << sector_size; /* 00000010: Sector size in bytes */ + stream << sectors_; /* 00000014: Sectors per cylinder */ + stream << heads_; /* 00000018: Heads per cylinder */ + stream << cylinders_; /* 0000001C: Cylinders */ for (int i = 0; i < 0x3f8; i++) { stream << zero; } - } else if (img_format == 2) { /* HDX file */ + } else if (img_format == IMG_FMT_HDX) { /* HDX file */ QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); quint64 signature = 0xD778A82044445459; - stream << signature; /* 00000000: Signature */ - stream << size; /* 00000008: Full size of the data (64-bit) */ - stream << sector_size; /* 00000010: Sector size in bytes */ - stream << sectors_; /* 00000014: Sectors per cylinder */ - stream << heads_; /* 00000018: Heads per cylinder */ - stream << cylinders_; /* 0000001C: Cylinders */ - stream << zero; /* 00000020: [Translation] Sectors per cylinder */ - stream << zero; /* 00000004: [Translation] Heads per cylinder */ - } else if (img_format >= 3) { /* VHD file */ + stream << signature; /* 00000000: Signature */ + stream << size; /* 00000008: Full size of the data (64-bit) */ + stream << sector_size; /* 00000010: Sector size in bytes */ + stream << sectors_; /* 00000014: Sectors per cylinder */ + stream << heads_; /* 00000018: Heads per cylinder */ + stream << cylinders_; /* 0000001C: Cylinders */ + stream << zero; /* 00000020: [Translation] Sectors per cylinder */ + stream << zero; /* 00000004: [Translation] Heads per cylinder */ + } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ file.close(); - MVHDGeom _86box_geometry{}; - int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; + MVHDGeom _86box_geometry {}; + int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; switch (img_format) { - case 3: - { - connect(this, &HarddiskDialog::fileProgress, this, [this] (int value) { ui->progressBar->setValue(value); QApplication::processEvents(); } ); - ui->progressBar->setVisible(true); - [&_86box_geometry, fileName, this] { - _86box_geometry = create_drive_vhd_fixed(fileName, this, cylinders_, heads_, sectors_); - }(); - } - break; - case 4: - _86box_geometry = create_drive_vhd_dynamic(fileName, cylinders_, heads_, sectors_, block_size); - break; - case 5: - QString vhdParent = QFileDialog::getOpenFileName( - this, - tr("Select the parent VHD"), - QString(), - tr("VHD files") % - util::DlgFilter({ "vhd" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + case IMG_FMT_VHD_FIXED: + { + connect(this, &HarddiskDialog::fileProgress, this, [this](int value) { ui->progressBar->setValue(value); QApplication::processEvents(); }); + ui->progressBar->setVisible(true); + [&_86box_geometry, fileName, this] { + _86box_geometry = create_drive_vhd_fixed(fileName, this, cylinders_, heads_, sectors_); + }(); + } + break; + case IMG_FMT_VHD_DYNAMIC: + _86box_geometry = create_drive_vhd_dynamic(fileName, cylinders_, heads_, sectors_, block_size); + break; + case IMG_FMT_VHD_DIFF: + QString vhdParent = QFileDialog::getOpenFileName( + this, + tr("Select the parent VHD"), + QString(), + tr("VHD files") % util::DlgFilter({ "vhd" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - if (vhdParent.isEmpty()) { - return; - } - _86box_geometry = create_drive_vhd_diff(fileName, vhdParent, block_size); - break; + if (vhdParent.isEmpty()) { + return; + } + _86box_geometry = create_drive_vhd_diff(fileName, vhdParent, block_size); + break; } - if (_86box_geometry.cyl == 0 && - _86box_geometry.heads == 0 && - _86box_geometry.spt == 0) - { + if (_86box_geometry.cyl == 0 && _86box_geometry.heads == 0 && _86box_geometry.spt == 0) { QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory.")); return; - } - else if (img_format != 5) { + } else if (img_format != IMG_FMT_VHD_DIFF) { QMessageBox::information(this, tr("Disk image created"), tr("Remember to partition and format the newly-created drive.")); } @@ -415,23 +430,23 @@ void HarddiskDialog::onCreateNewFile() { ui->lineEditHeads->setText(QString::number(_86box_geometry.heads)); ui->lineEditSectors->setText(QString::number(_86box_geometry.spt)); cylinders_ = _86box_geometry.cyl; - heads_ = _86box_geometry.heads; - sectors_ = _86box_geometry.spt; + heads_ = _86box_geometry.heads; + sectors_ = _86box_geometry.spt; setResult(QDialog::Accepted); return; } // formats 0, 1 and 2 - connect(this, &HarddiskDialog::fileProgress, this, [this] (int value) { ui->progressBar->setValue(value); QApplication::processEvents(); } ); + connect(this, &HarddiskDialog::fileProgress, this, [this](int value) { ui->progressBar->setValue(value); QApplication::processEvents(); }); ui->progressBar->setVisible(true); [size, &file, this] { QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); QByteArray buf(1048576, 0); - uint64_t mibBlocks = size >> 20; - uint64_t restBlock = size & 0xfffff; + uint64_t mibBlocks = size >> 20; + uint64_t restBlock = size & 0xfffff; if (restBlock) { stream.writeRawData(buf.data(), restBlock); @@ -450,7 +465,9 @@ void HarddiskDialog::onCreateNewFile() { setResult(QDialog::Accepted); } -static void adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) { +static void +adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) +{ if (vhd_geometry->spt <= 63) return; @@ -462,17 +479,17 @@ static void adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) { if (remainder > 0) desired_sectors -= remainder; - vhd_geometry->cyl = desired_sectors / (16 * 63); + vhd_geometry->cyl = desired_sectors / (16 * 63); vhd_geometry->heads = 16; - vhd_geometry->spt = 63; + vhd_geometry->spt = 63; } -void HarddiskDialog::recalcSelection() { +void +HarddiskDialog::recalcSelection() +{ int selection = 127; for (int i = 0; i < 127; i++) { - if ((cylinders_ == hdd_table[i][0]) && - (heads_ == hdd_table[i][1]) && - (sectors_ == hdd_table[i][2])) + if ((cylinders_ == hdd_table[i][0]) && (heads_ == hdd_table[i][1]) && (sectors_ == hdd_table[i][2])) selection = i; } if ((selection == 127) && (heads_ == 16) && (sectors_ == 63)) { @@ -481,7 +498,9 @@ void HarddiskDialog::recalcSelection() { ui->comboBoxType->setCurrentIndex(selection); } -void HarddiskDialog::onExistingFileSelected(const QString &fileName) { +void +HarddiskDialog::onExistingFileSelected(const QString &fileName) +{ // TODO : Over to non-existing file selected /* if (!(existing & 1)) { @@ -502,16 +521,16 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { } */ - uint64_t size = 0; + uint64_t size = 0; uint32_t sector_size = 0; - uint32_t sectors = 0; - uint32_t heads = 0; - uint32_t cylinders = 0; - int vhd_error = 0; + uint32_t sectors = 0; + uint32_t heads = 0; + uint32_t cylinders = 0; + int vhd_error = 0; ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); QFile file(fileName); - if (! file.open(QIODevice::ReadOnly)) { + if (!file.open(QIODevice::ReadOnly)) { QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable.")); return; } @@ -533,7 +552,7 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { stream >> heads; stream >> cylinders; } else if (image_is_vhd(fileNameUtf8.data(), 1)) { - MVHDMeta* vhd = mvhd_open(fileNameUtf8.data(), 0, &vhd_error); + MVHDMeta *vhd = mvhd_open(fileNameUtf8.data(), 0, &vhd_error); if (vhd == nullptr) { QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable")); return; @@ -555,9 +574,9 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { MVHDGeom vhd_geom = mvhd_get_geometry(vhd); adjust_vhd_geometry_for_86box(&vhd_geom); cylinders = vhd_geom.cyl; - heads = vhd_geom.heads; - sectors = vhd_geom.spt; - size = static_cast(cylinders * heads * sectors * 512); + heads = vhd_geom.heads; + sectors = vhd_geom.spt; + size = static_cast(cylinders * heads * sectors * 512); mvhd_close(vhd); } else { size = file.size(); @@ -579,7 +598,7 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { } } else { sectors = 63; - heads = 16; + heads = 16; } cylinders = ((size >> 9) / heads) / sectors; @@ -590,8 +609,8 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { return; } - heads_ = heads; - sectors_ = sectors; + heads_ = heads; + sectors_ = sectors; cylinders_ = cylinders; ui->lineEditCylinders->setText(QString::number(cylinders)); ui->lineEditHeads->setText(QString::number(heads)); @@ -607,13 +626,18 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } -void HarddiskDialog::recalcSize() { - if (disallowSizeModifications) return; +void +HarddiskDialog::recalcSize() +{ + if (disallowSizeModifications) + return; uint64_t size = (static_cast(cylinders_) * static_cast(heads_) * static_cast(sectors_)) << 9; ui->lineEditSize->setText(QString::number(size >> 20)); } -bool HarddiskDialog::checkAndAdjustSectors() { +bool +HarddiskDialog::checkAndAdjustSectors() +{ if (sectors_ > max_sectors) { sectors_ = max_sectors; ui->lineEditSectors->setText(QString::number(max_sectors)); @@ -624,7 +648,9 @@ bool HarddiskDialog::checkAndAdjustSectors() { return true; } -bool HarddiskDialog::checkAndAdjustHeads() { +bool +HarddiskDialog::checkAndAdjustHeads() +{ if (heads_ > max_heads) { heads_ = max_heads; ui->lineEditHeads->setText(QString::number(max_heads)); @@ -635,7 +661,9 @@ bool HarddiskDialog::checkAndAdjustHeads() { return true; } -bool HarddiskDialog::checkAndAdjustCylinders() { +bool +HarddiskDialog::checkAndAdjustCylinders() +{ if (cylinders_ > max_cylinders) { cylinders_ = max_cylinders; ui->lineEditCylinders->setText(QString::number(max_cylinders)); @@ -646,44 +674,45 @@ bool HarddiskDialog::checkAndAdjustCylinders() { return true; } - -void HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) { +void +HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) +{ int chanIdx = 0; if (index < 0) { return; } switch (ui->comboBoxBus->currentData().toInt()) { - case HDD_BUS_DISABLED: - default: - max_sectors = max_heads = max_cylinders = 0; - break; - case HDD_BUS_MFM: - max_sectors = 26; /* 17 for MFM, 26 for RLL. */ - max_heads = 15; - max_cylinders = 2047; - break; - case HDD_BUS_XTA: - max_sectors = 63; - max_heads = 16; - max_cylinders = 1023; - break; - case HDD_BUS_ESDI: - max_sectors = 99; /* ESDI drives usually had 32 to 43 sectors per track. */ - max_heads = 16; - max_cylinders = 266305; - break; - case HDD_BUS_IDE: - max_sectors = 63; - max_heads = 255; - max_cylinders = 266305; - break; - case HDD_BUS_ATAPI: - case HDD_BUS_SCSI: - max_sectors = 99; - max_heads = 255; - max_cylinders = 266305; - break; + case HDD_BUS_DISABLED: + default: + max_sectors = max_heads = max_cylinders = 0; + break; + case HDD_BUS_MFM: + max_sectors = 26; /* 17 for MFM, 26 for RLL. */ + max_heads = 15; + max_cylinders = 2047; + break; + case HDD_BUS_XTA: + max_sectors = 63; + max_heads = 16; + max_cylinders = 1023; + break; + case HDD_BUS_ESDI: + max_sectors = 99; /* ESDI drives usually had 32 to 43 sectors per track. */ + max_heads = 16; + max_cylinders = 266305; + break; + case HDD_BUS_IDE: + max_sectors = 63; + max_heads = 255; + max_cylinders = 266305; + break; + case HDD_BUS_ATAPI: + case HDD_BUS_SCSI: + max_sectors = 99; + max_heads = 255; + max_cylinders = 266305; + break; } checkAndAdjustCylinders(); @@ -707,8 +736,7 @@ void HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) { Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt()); Harddrives::populateSpeeds(ui->comboBoxSpeed->model(), ui->comboBoxBus->currentData().toInt()); - switch (ui->comboBoxBus->currentData().toInt()) - { + switch (ui->comboBoxBus->currentData().toInt()) { case HDD_BUS_MFM: chanIdx = (Harddrives::busTrackClass->next_free_mfm_channel()); break; @@ -727,13 +755,16 @@ void HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) { break; } - if (chanIdx == 0xFF) chanIdx = 0; + if (chanIdx == 0xFF) + chanIdx = 0; ui->comboBoxChannel->setCurrentIndex(chanIdx); } -void HarddiskDialog::on_lineEditSize_textEdited(const QString &text) { +void +HarddiskDialog::on_lineEditSize_textEdited(const QString &text) +{ disallowSizeModifications = true; - uint32_t size = text.toUInt(); + uint32_t size = text.toUInt(); /* This is needed to ensure VHD standard compliance. */ hdd_image_calc_chs(&cylinders_, &heads_, §ors_, size); ui->lineEditCylinders->setText(QString::number(cylinders_)); @@ -748,7 +779,9 @@ void HarddiskDialog::on_lineEditSize_textEdited(const QString &text) { disallowSizeModifications = false; } -void HarddiskDialog::on_lineEditCylinders_textEdited(const QString &text) { +void +HarddiskDialog::on_lineEditCylinders_textEdited(const QString &text) +{ cylinders_ = text.toUInt(); if (checkAndAdjustCylinders()) { recalcSize(); @@ -756,7 +789,9 @@ void HarddiskDialog::on_lineEditCylinders_textEdited(const QString &text) { } } -void HarddiskDialog::on_lineEditHeads_textEdited(const QString &text) { +void +HarddiskDialog::on_lineEditHeads_textEdited(const QString &text) +{ heads_ = text.toUInt(); if (checkAndAdjustHeads()) { recalcSize(); @@ -764,7 +799,9 @@ void HarddiskDialog::on_lineEditHeads_textEdited(const QString &text) { } } -void HarddiskDialog::on_lineEditSectors_textEdited(const QString &text) { +void +HarddiskDialog::on_lineEditSectors_textEdited(const QString &text) +{ sectors_ = text.toUInt(); if (checkAndAdjustSectors()) { recalcSize(); @@ -772,21 +809,23 @@ void HarddiskDialog::on_lineEditSectors_textEdited(const QString &text) { } } -void HarddiskDialog::on_comboBoxType_currentIndexChanged(int index) { +void +HarddiskDialog::on_comboBoxType_currentIndexChanged(int index) +{ if (index < 0) { return; } if ((index != 127) && (index != 128)) { cylinders_ = hdd_table[index][0]; - heads_ = hdd_table[index][1]; - sectors_ = hdd_table[index][2]; + heads_ = hdd_table[index][1]; + sectors_ = hdd_table[index][2]; ui->lineEditCylinders->setText(QString::number(cylinders_)); ui->lineEditHeads->setText(QString::number(heads_)); ui->lineEditSectors->setText(QString::number(sectors_)); recalcSize(); } else if (index == 128) { - heads_ = 16; + heads_ = 16; sectors_ = 63; ui->lineEditHeads->setText(QString::number(heads_)); ui->lineEditSectors->setText(QString::number(sectors_)); @@ -798,9 +837,12 @@ void HarddiskDialog::on_comboBoxType_currentIndexChanged(int index) { checkAndAdjustSectors(); } -void HarddiskDialog::accept() +void +HarddiskDialog::accept() { - if (ui->fileField->createFile()) onCreateNewFile(); - else setResult(QDialog::Accepted); + if (ui->fileField->createFile()) + onCreateNewFile(); + else + setResult(QDialog::Accepted); QDialog::done(result()); } diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index f876d35dd..a630bd8e2 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -7,17 +7,16 @@ namespace Ui { class HarddiskDialog; } -class HarddiskDialog : public QDialog -{ +class HarddiskDialog : public QDialog { Q_OBJECT public: explicit HarddiskDialog(bool existing, QWidget *parent = nullptr); ~HarddiskDialog(); - uint8_t bus() const; - uint8_t channel() const; - QString fileName() const; + uint8_t bus() const; + uint8_t channel() const; + QString fileName() const; uint32_t cylinders() const { return cylinders_; } uint32_t heads() const { return heads_; } uint32_t sectors() const { return sectors_; } @@ -38,7 +37,8 @@ private slots: void on_comboBoxBus_currentIndexChanged(int index); void on_comboBoxFormat_currentIndexChanged(int index); void onCreateNewFile(); - void onExistingFileSelected(const QString& fileName); + void onExistingFileSelected(const QString &fileName); + private: Ui::HarddiskDialog *ui; @@ -46,10 +46,10 @@ private: uint32_t heads_; uint32_t sectors_; - uint32_t max_sectors = 0; - uint32_t max_heads = 0; + uint32_t max_sectors = 0; + uint32_t max_heads = 0; uint32_t max_cylinders = 0; - + bool disallowSizeModifications = false; bool checkAndAdjustCylinders(); diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index 661e7992c..7d3beaa2b 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -24,7 +24,9 @@ extern "C" { #include -void Harddrives::populateBuses(QAbstractItemModel *model) { +void +Harddrives::populateBuses(QAbstractItemModel *model) +{ model->removeRows(0, model->rowCount()); model->insertRows(0, 6); model->setData(model->index(0, 0), "MFM/RLL"); @@ -42,7 +44,9 @@ void Harddrives::populateBuses(QAbstractItemModel *model) { model->setData(model->index(5, 0), HDD_BUS_SCSI, Qt::UserRole); } -void Harddrives::populateRemovableBuses(QAbstractItemModel *model) { +void +Harddrives::populateRemovableBuses(QAbstractItemModel *model) +{ model->removeRows(0, model->rowCount()); model->insertRows(0, 3); model->setData(model->index(0, 0), QObject::tr("Disabled")); @@ -54,7 +58,9 @@ void Harddrives::populateRemovableBuses(QAbstractItemModel *model) { model->setData(model->index(2, 0), HDD_BUS_SCSI, Qt::UserRole); } -void Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) { +void +Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) +{ int num_preset; switch (bus) { @@ -76,29 +82,31 @@ void Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) { } } -void Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) { +void +Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) +{ model->removeRows(0, model->rowCount()); - int busRows = 0; - int shifter = 1; - int orer = 1; + int busRows = 0; + int shifter = 1; + int orer = 1; int subChannelWidth = 1; switch (bus) { - case HDD_BUS_MFM: - case HDD_BUS_XTA: - case HDD_BUS_ESDI: - busRows = 2; - break; - case HDD_BUS_IDE: - case HDD_BUS_ATAPI: - busRows = 8; - break; - case HDD_BUS_SCSI: - shifter = 4; - orer = 15; - busRows = 64; - subChannelWidth = 2; - break; + case HDD_BUS_MFM: + case HDD_BUS_XTA: + case HDD_BUS_ESDI: + busRows = 2; + break; + case HDD_BUS_IDE: + case HDD_BUS_ATAPI: + busRows = 8; + break; + case HDD_BUS_SCSI: + shifter = 4; + orer = 15; + busRows = 64; + subChannelWidth = 2; + break; } model->insertRows(0, busRows); @@ -109,30 +117,32 @@ void Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) { } } -QString Harddrives::BusChannelName(uint8_t bus, uint8_t channel) { +QString +Harddrives::BusChannelName(uint8_t bus, uint8_t channel) +{ QString busName; - switch(bus) { - case HDD_BUS_DISABLED: - busName = QString(QObject::tr("Disabled")); - break; - case HDD_BUS_MFM: - busName = QString("MFM/RLL (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_XTA: - busName = QString("XTA (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_ESDI: - busName = QString("ESDI (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_IDE: - busName = QString("IDE (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_ATAPI: - busName = QString("ATAPI (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_SCSI: - busName = QString("SCSI (%1:%2)").arg(channel >> 4).arg(channel & 15, 2, 10, QChar('0')); - break; + switch (bus) { + case HDD_BUS_DISABLED: + busName = QString(QObject::tr("Disabled")); + break; + case HDD_BUS_MFM: + busName = QString("MFM/RLL (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_XTA: + busName = QString("XTA (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_ESDI: + busName = QString("ESDI (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_IDE: + busName = QString("IDE (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_ATAPI: + busName = QString("ATAPI (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_SCSI: + busName = QString("SCSI (%1:%2)").arg(channel >> 4).arg(channel & 15, 2, 10, QChar('0')); + break; } return busName; diff --git a/src/qt/qt_harddrive_common.hpp b/src/qt/qt_harddrive_common.hpp index 6e133506f..2aca184b3 100644 --- a/src/qt/qt_harddrive_common.hpp +++ b/src/qt/qt_harddrive_common.hpp @@ -7,10 +7,10 @@ class QAbstractItemModel; class SettingsBusTracking; namespace Harddrives { - void populateBuses(QAbstractItemModel* model); - void populateRemovableBuses(QAbstractItemModel* model); - void populateBusChannels(QAbstractItemModel* model, int bus); - void populateSpeeds(QAbstractItemModel* model, int bus); - QString BusChannelName(uint8_t bus, uint8_t channel); - inline SettingsBusTracking* busTrackClass = nullptr; +void populateBuses(QAbstractItemModel *model); +void populateRemovableBuses(QAbstractItemModel *model); +void populateBusChannels(QAbstractItemModel *model, int bus); +void populateSpeeds(QAbstractItemModel *model, int bus); +QString BusChannelName(uint8_t bus, uint8_t channel); +inline SettingsBusTracking *busTrackClass = nullptr; }; diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index dd0eed632..f158e7d62 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -33,85 +33,77 @@ extern "C" { #include <86box/video.h> } -void HardwareRenderer::resizeGL(int w, int h) +void +HardwareRenderer::resizeGL(int w, int h) { m_context->makeCurrent(this); glViewport(0, 0, qRound(w * devicePixelRatio()), qRound(h * devicePixelRatio())); } -#define PROGRAM_VERTEX_ATTRIBUTE 0 +#define PROGRAM_VERTEX_ATTRIBUTE 0 #define PROGRAM_TEXCOORD_ATTRIBUTE 1 -void HardwareRenderer::initializeGL() +void +HardwareRenderer::initializeGL() { m_context->makeCurrent(this); initializeOpenGLFunctions(); auto image = QImage(2048, 2048, QImage::Format_RGB32); image.fill(0xff000000); m_texture = new QOpenGLTexture(image); - m_blt = new QOpenGLTextureBlitter; + m_blt = new QOpenGLTextureBlitter; m_blt->setRedBlueSwizzle(true); m_blt->create(); - QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); - const char *vsrc = - "attribute highp vec4 VertexCoord;\n" - "attribute mediump vec4 TexCoord;\n" - "varying mediump vec4 texc;\n" - "uniform mediump mat4 MVPMatrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = MVPMatrix * VertexCoord;\n" - " texc = TexCoord;\n" - "}\n"; - QString vsrccore = - "in highp vec4 VertexCoord;\n" - "in mediump vec4 TexCoord;\n" - "out mediump vec4 texc;\n" - "uniform mediump mat4 MVPMatrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = MVPMatrix * VertexCoord;\n" - " texc = TexCoord;\n" - "}\n"; - if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) - { + QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); + const char *vsrc = "attribute highp vec4 VertexCoord;\n" + "attribute mediump vec4 TexCoord;\n" + "varying mediump vec4 texc;\n" + "uniform mediump mat4 MVPMatrix;\n" + "void main(void)\n" + "{\n" + " gl_Position = MVPMatrix * VertexCoord;\n" + " texc = TexCoord;\n" + "}\n"; + QString vsrccore = "in highp vec4 VertexCoord;\n" + "in mediump vec4 TexCoord;\n" + "out mediump vec4 texc;\n" + "uniform mediump mat4 MVPMatrix;\n" + "void main(void)\n" + "{\n" + " gl_Position = MVPMatrix * VertexCoord;\n" + " texc = TexCoord;\n" + "}\n"; + if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) { vsrccore.prepend("#version 300 es\n"); vshader->compileSourceCode(vsrccore); - } - else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) - { + } else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) { vsrccore.prepend("#version 130\n"); vshader->compileSourceCode(vsrccore); - } - else vshader->compileSourceCode(vsrc); + } else + vshader->compileSourceCode(vsrc); - QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); - const char *fsrc = - "uniform sampler2D texture;\n" - "varying mediump vec4 texc;\n" - "void main(void)\n" - "{\n" - " gl_FragColor = texture2D(texture, texc.st).bgra;\n" - "}\n"; - QString fsrccore = - "uniform sampler2D texture;\n" - "in mediump vec4 texc;\n" - "out highp vec4 FragColor;\n" - "void main(void)\n" - "{\n" - " FragColor = texture2D(texture, texc.st).bgra;\n" - "}\n"; - if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) - { + QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); + const char *fsrc = "uniform sampler2D texture;\n" + "varying mediump vec4 texc;\n" + "void main(void)\n" + "{\n" + " gl_FragColor = texture2D(texture, texc.st).bgra;\n" + "}\n"; + QString fsrccore = "uniform sampler2D texture;\n" + "in mediump vec4 texc;\n" + "out highp vec4 FragColor;\n" + "void main(void)\n" + "{\n" + " FragColor = texture2D(texture, texc.st).bgra;\n" + "}\n"; + if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) { fsrccore.prepend("#version 300 es\n"); fshader->compileSourceCode(fsrccore); - } - else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) - { + } else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) { fsrccore.prepend("#version 130\n"); fshader->compileSourceCode(fsrccore); - } - else fshader->compileSourceCode(fsrc); + } else + fshader->compileSourceCode(fsrc); m_prog = new QOpenGLShaderProgram; m_prog->addShader(vshader); @@ -144,95 +136,115 @@ void HardwareRenderer::initializeGL() m_context->swapBuffers(this); } -void HardwareRenderer::paintGL() { +void +HardwareRenderer::paintGL() +{ m_context->makeCurrent(this); glClear(GL_COLOR_BUFFER_BIT); QVector verts, texcoords; - QMatrix4x4 mat; + QMatrix4x4 mat; mat.setToIdentity(); - mat.ortho(QRectF(0, 0, (qreal)width(), (qreal)height())); - verts.push_back(QVector2D((float)destination.x(), (float)destination.y())); - verts.push_back(QVector2D((float)destination.x(), (float)destination.y() + (float)destination.height())); - verts.push_back(QVector2D((float)destination.x() + (float)destination.width(), (float)destination.y() + (float)destination.height())); - verts.push_back(QVector2D((float)destination.x() + (float)destination.width(), (float)destination.y())); - texcoords.push_back(QVector2D((float)source.x() / 2048.f, (float)(source.y()) / 2048.f)); - texcoords.push_back(QVector2D((float)source.x() / 2048.f, (float)(source.y() + source.height()) / 2048.f)); - texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y() + source.height()) / 2048.f)); - texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y()) / 2048.f)); + mat.ortho(QRectF(0, 0, (qreal) width(), (qreal) height())); + verts.push_back(QVector2D((float) destination.x(), (float) destination.y())); + verts.push_back(QVector2D((float) destination.x(), (float) destination.y() + (float) destination.height())); + verts.push_back(QVector2D((float) destination.x() + (float) destination.width(), (float) destination.y() + (float) destination.height())); + verts.push_back(QVector2D((float) destination.x() + (float) destination.width(), (float) destination.y())); + texcoords.push_back(QVector2D((float) source.x() / 2048.f, (float) (source.y()) / 2048.f)); + texcoords.push_back(QVector2D((float) source.x() / 2048.f, (float) (source.y() + source.height()) / 2048.f)); + texcoords.push_back(QVector2D((float) (source.x() + source.width()) / 2048.f, (float) (source.y() + source.height()) / 2048.f)); + texcoords.push_back(QVector2D((float) (source.x() + source.width()) / 2048.f, (float) (source.y()) / 2048.f)); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].write(0, verts.data(), sizeof(QVector2D) * 4); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].write(0, texcoords.data(), sizeof(QVector2D) * 4); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].write(0, verts.data(), sizeof(QVector2D) * 4); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].write(0, texcoords.data(), sizeof(QVector2D) * 4); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); m_prog->setUniformValue("MVPMatrix", mat); m_prog->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE); m_prog->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); m_prog->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2, 0); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); m_prog->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2, 0); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); + m_prog->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2, 0); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); + m_prog->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2, 0); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); m_texture->bind(); m_texture->setMinMagFilters(video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest, video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } -void HardwareRenderer::setRenderType(RenderType type) { +void +HardwareRenderer::setRenderType(RenderType type) +{ QSurfaceFormat format; switch (type) { - case RenderType::OpenGL3: - format.setVersion(3, 0); - format.setProfile(QSurfaceFormat::CoreProfile); - case RenderType::OpenGL: - format.setRenderableType(QSurfaceFormat::OpenGL); - break; - case RenderType::OpenGLES: - format.setRenderableType(QSurfaceFormat::OpenGLES); - break; + case RenderType::OpenGL3: + format.setVersion(3, 0); + format.setProfile(QSurfaceFormat::CoreProfile); + case RenderType::OpenGL: + format.setRenderableType(QSurfaceFormat::OpenGL); + break; + case RenderType::OpenGLES: + format.setRenderableType(QSurfaceFormat::OpenGLES); + break; } format.setSwapInterval(0); setFormat(format); } -void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { - auto tval = this; - void* nuldata = 0; - if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; +void +HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) +{ + auto tval = this; + void *nuldata = 0; + if (memcmp(&tval, &nuldata, sizeof(void *)) == 0) + return; auto origSource = source; - if (!m_texture || !m_texture->isCreated()) - { + if (!m_texture || !m_texture->isCreated()) { buf_usage[buf_idx].clear(); source.setRect(x, y, w, h); return; } m_context->makeCurrent(this); #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - m_texture->setData(x, y, 0, w, h, 0, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)((uintptr_t)imagebufs[buf_idx].get() + (uintptr_t)(2048 * 4 * y + x * 4)), &m_transferOptions); + m_texture->setData(x, y, 0, w, h, 0, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void *) ((uintptr_t) imagebufs[buf_idx].get() + (uintptr_t) (2048 * 4 * y + x * 4)), &m_transferOptions); #else m_texture->bind(); glPixelStorei(GL_UNPACK_ROW_LENGTH, 2048); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)((uintptr_t)imagebufs[buf_idx].get() + (uintptr_t)(2048 * 4 * y + x * 4))); + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void *) ((uintptr_t) imagebufs[buf_idx].get() + (uintptr_t) (2048 * 4 * y + x * 4))); m_texture->release(); #endif buf_usage[buf_idx].clear(); source.setRect(x, y, w, h); - if (origSource != source) onResize(this->width(), this->height()); + if (origSource != source) + onResize(this->width(), this->height()); update(); } -void HardwareRenderer::resizeEvent(QResizeEvent *event) { +void +HardwareRenderer::resizeEvent(QResizeEvent *event) +{ onResize(width(), height()); QOpenGLWindow::resizeEvent(event); } -bool HardwareRenderer::event(QEvent *event) +bool +HardwareRenderer::event(QEvent *event) { bool res = false; - if (!eventDelegate(event, res)) return QOpenGLWindow::event(event); + if (!eventDelegate(event, res)) + return QOpenGLWindow::event(event); return res; } -std::vector> HardwareRenderer::getBuffers() +std::vector> +HardwareRenderer::getBuffers() { - std::vector> buffers; + std::vector> buffers; buffers.push_back(std::make_tuple(imagebufs[0].get(), &buf_usage[0])); buffers.push_back(std::make_tuple(imagebufs[1].get(), &buf_usage[1])); diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index 30515a2e8..da23c4b05 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -24,21 +24,20 @@ #include "qt_renderercommon.hpp" #ifdef WAYLAND -#include "wl_mouse.hpp" +# include "wl_mouse.hpp" #endif -class HardwareRenderer : public QOpenGLWindow, protected QOpenGLFunctions, public RendererCommon -{ - Q_OBJECT +class HardwareRenderer : public QOpenGLWindow, protected QOpenGLFunctions, public RendererCommon { + Q_OBJECT private: - bool wayland = false; - QOpenGLContext* m_context; - QOpenGLTexture* m_texture{nullptr}; - QOpenGLShaderProgram* m_prog{nullptr}; - QOpenGLTextureBlitter* m_blt{nullptr}; - QOpenGLBuffer m_vbo[2]; - QOpenGLVertexArrayObject m_vao; + bool wayland = false; + QOpenGLContext *m_context; + QOpenGLTexture *m_texture { nullptr }; + QOpenGLShaderProgram *m_prog { nullptr }; + QOpenGLTextureBlitter *m_blt { nullptr }; + QOpenGLBuffer m_vbo[2]; + QOpenGLVertexArrayObject m_vao; QOpenGLPixelTransferOptions m_transferOptions; public: @@ -50,13 +49,14 @@ public: void resizeGL(int w, int h) override; void initializeGL() override; void paintGL() override; - void exposeEvent(QExposeEvent* event) override + void exposeEvent(QExposeEvent *event) override { onResize(size().width(), size().height()); } - std::vector> getBuffers() override; - HardwareRenderer(QWidget* parent = nullptr, RenderType rtype = RenderType::OpenGL) - : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()), QOpenGLFunctions() + std::vector> getBuffers() override; + HardwareRenderer(QWidget *parent = nullptr, RenderType rtype = RenderType::OpenGL) + : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()) + , QOpenGLFunctions() { imagebufs[0] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); imagebufs[1] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); @@ -80,7 +80,8 @@ public: ~HardwareRenderer() { m_context->makeCurrent(this); - if (m_blt) m_blt->destroy(); + if (m_blt) + m_blt->destroy(); m_prog->release(); delete m_prog; m_prog = nullptr; @@ -88,7 +89,6 @@ public: delete m_context; } - void setRenderType(RenderType type); public slots: @@ -98,5 +98,5 @@ protected: std::array, 2> imagebufs; void resizeEvent(QResizeEvent *event) override; - bool event(QEvent* event) override; + bool event(QEvent *event) override; }; diff --git a/src/qt/qt_joystickconfiguration.cpp b/src/qt/qt_joystickconfiguration.cpp index 54aec5c6d..a9c53c07e 100644 --- a/src/qt/qt_joystickconfiguration.cpp +++ b/src/qt/qt_joystickconfiguration.cpp @@ -22,24 +22,23 @@ extern "C" { #include <86box/gameport.h> } - #include #include #include #include "qt_models_common.hpp" -JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget *parent) : - QDialog(parent), - ui(new Ui::JoystickConfiguration), - type(type), - joystick_nr(joystick_nr) +JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget *parent) + : QDialog(parent) + , ui(new Ui::JoystickConfiguration) + , type(type) + , joystick_nr(joystick_nr) { ui->setupUi(this); auto model = ui->comboBoxDevice->model(); Models::AddEntry(model, "None", 0); for (int c = 0; c < joysticks_present; c++) { - Models::AddEntry(model, plat_joystick_state[c].name, c+1); + Models::AddEntry(model, plat_joystick_state[c].name, c + 1); } ui->comboBoxDevice->setCurrentIndex(joystick_state[joystick_nr].plat_joystick_nr); @@ -51,35 +50,45 @@ JoystickConfiguration::~JoystickConfiguration() delete ui; } -int JoystickConfiguration::selectedDevice() { +int +JoystickConfiguration::selectedDevice() +{ return ui->comboBoxDevice->currentIndex(); } -int JoystickConfiguration::selectedAxis(int axis) { - auto* cbox = findChild(QString("cboxAxis%1").arg(QString::number(axis))); +int +JoystickConfiguration::selectedAxis(int axis) +{ + auto *cbox = findChild(QString("cboxAxis%1").arg(QString::number(axis))); if (cbox == nullptr) { return 0; } return cbox->currentIndex(); } -int JoystickConfiguration::selectedButton(int button) { - auto* cbox = findChild(QString("cboxButton%1").arg(QString::number(button))); +int +JoystickConfiguration::selectedButton(int button) +{ + auto *cbox = findChild(QString("cboxButton%1").arg(QString::number(button))); if (cbox == nullptr) { return 0; } return cbox->currentIndex(); } -int JoystickConfiguration::selectedPov(int pov) { - auto* cbox = findChild(QString("cboxPov%1").arg(QString::number(pov))); +int +JoystickConfiguration::selectedPov(int pov) +{ + auto *cbox = findChild(QString("cboxPov%1").arg(QString::number(pov))); if (cbox == nullptr) { return 0; } return cbox->currentIndex(); } -void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { +void +JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) +{ for (auto w : widgets) { ui->ct->removeWidget(w); w->deleteLater(); @@ -91,11 +100,11 @@ void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { } int joystick = index - 1; - int row = 0; + int row = 0; for (int c = 0; c < joystick_get_axis_count(type); c++) { /*Combo box*/ auto label = new QLabel(joystick_get_axis_name(type, c), this); - auto cbox = new QComboBox(this); + auto cbox = new QComboBox(this); cbox->setObjectName(QString("cboxAxis%1").arg(QString::number(c))); auto model = cbox->model(); @@ -135,7 +144,7 @@ void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { for (int c = 0; c < joystick_get_button_count(type); c++) { auto label = new QLabel(joystick_get_button_name(type, c), this); - auto cbox = new QComboBox(this); + auto cbox = new QComboBox(this); cbox->setObjectName(QString("cboxButton%1").arg(QString::number(c))); auto model = cbox->model(); @@ -155,11 +164,11 @@ void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { } for (int c = 0; c < joystick_get_pov_count(type) * 2; c++) { - QLabel* label; + QLabel *label; if (c & 1) { - label = new QLabel(QString("%1 (Y axis)").arg(joystick_get_pov_name(type, c/2)), this); + label = new QLabel(QString("%1 (Y axis)").arg(joystick_get_pov_name(type, c / 2)), this); } else { - label = new QLabel(QString("%1 (X axis)").arg(joystick_get_pov_name(type, c/2)), this); + label = new QLabel(QString("%1 (X axis)").arg(joystick_get_pov_name(type, c / 2)), this); } auto cbox = new QComboBox(this); cbox->setObjectName(QString("cboxPov%1").arg(QString::number(c))); @@ -179,17 +188,17 @@ void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { if (mapping & POV_X) cbox->setCurrentIndex((mapping & 3) * 2); else if (mapping & POV_Y) - cbox->setCurrentIndex((mapping & 3)*2 + 1); + cbox->setCurrentIndex((mapping & 3) * 2 + 1); else cbox->setCurrentIndex(mapping + nr_povs * 2); mapping = joystick_state[joystick_nr].pov_mapping[c][1]; if (mapping & POV_X) - cbox->setCurrentIndex((mapping & 3)*2); + cbox->setCurrentIndex((mapping & 3) * 2); else if (mapping & POV_Y) - cbox->setCurrentIndex((mapping & 3)*2 + 1); + cbox->setCurrentIndex((mapping & 3) * 2 + 1); else - cbox->setCurrentIndex(mapping + nr_povs*2); + cbox->setCurrentIndex(mapping + nr_povs * 2); ui->ct->addWidget(label, row, 0); ui->ct->addWidget(cbox, row, 1); diff --git a/src/qt/qt_joystickconfiguration.hpp b/src/qt/qt_joystickconfiguration.hpp index b6882c52b..0b185ad73 100644 --- a/src/qt/qt_joystickconfiguration.hpp +++ b/src/qt/qt_joystickconfiguration.hpp @@ -7,8 +7,7 @@ namespace Ui { class JoystickConfiguration; } -class JoystickConfiguration : public QDialog -{ +class JoystickConfiguration : public QDialog { Q_OBJECT public: @@ -24,9 +23,9 @@ private slots: private: Ui::JoystickConfiguration *ui; - QList widgets; - int type; - int joystick_nr; + QList widgets; + int type; + int joystick_nr; }; #endif // QT_JOYSTICKCONFIGURATION_HPP diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index 9e93e882b..15aa51a7c 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -20,7 +20,7 @@ extern "C" { #define EMU_CPU_H // superhack - don't want timer.h to include cpu.h here, and some combo is preventing a compile -extern uint64_t tsc; +extern uint64_t tsc; #include <86box/hdd.h> #include <86box/timer.h> @@ -58,140 +58,154 @@ extern uint64_t tsc; #include -extern MainWindow* main_window; +extern MainWindow *main_window; namespace { - struct PixmapSetActive { - QPixmap normal; - QPixmap active; - void load(const QString& basePath); - }; - struct PixmapSetEmpty { - QPixmap normal; - QPixmap empty; - void load(const QString& basePath); - }; - struct PixmapSetEmptyActive { - QPixmap normal; - QPixmap active; - QPixmap empty; - QPixmap empty_active; - void load(QString basePath); - }; - struct Pixmaps { - PixmapSetEmpty cartridge; - PixmapSetEmptyActive cassette; - PixmapSetEmptyActive floppy_disabled; - PixmapSetEmptyActive floppy_525; - PixmapSetEmptyActive floppy_35; - PixmapSetEmptyActive cdrom; - PixmapSetEmptyActive zip; - PixmapSetEmptyActive mo; - PixmapSetActive hd; - PixmapSetEmptyActive net; - QPixmap sound; - }; +struct PixmapSetActive { + QPixmap normal; + QPixmap active; + void load(const QString &basePath); +}; +struct PixmapSetEmpty { + QPixmap normal; + QPixmap empty; + void load(const QString &basePath); +}; +struct PixmapSetEmptyActive { + QPixmap normal; + QPixmap active; + QPixmap empty; + QPixmap empty_active; + void load(QString basePath); +}; +struct Pixmaps { + PixmapSetEmpty cartridge; + PixmapSetEmptyActive cassette; + PixmapSetEmptyActive floppy_disabled; + PixmapSetEmptyActive floppy_525; + PixmapSetEmptyActive floppy_35; + PixmapSetEmptyActive cdrom; + PixmapSetEmptyActive zip; + PixmapSetEmptyActive mo; + PixmapSetActive hd; + PixmapSetEmptyActive net; + QPixmap sound; +}; - struct StateActive { - std::unique_ptr label; - PixmapSetActive* pixmaps = nullptr; - bool active = false; +struct StateActive { + std::unique_ptr label; + PixmapSetActive *pixmaps = nullptr; + bool active = false; - void setActive(bool b) { - if (!label || b == active) - return; - active = b; + void setActive(bool b) + { + if (!label || b == active) + return; + active = b; - refresh(); - } + refresh(); + } - void refresh() { - if (!label) - return; + void refresh() + { + if (!label) + return; + label->setPixmap(active ? pixmaps->active : pixmaps->normal); + } +}; +struct StateEmpty { + std::unique_ptr label; + PixmapSetEmpty *pixmaps = nullptr; + bool empty = false; + + void setEmpty(bool e) + { + if (!label || e == empty) + return; + empty = e; + + refresh(); + } + + void refresh() + { + if (!label) + return; + label->setPixmap(empty ? pixmaps->empty : pixmaps->normal); + } +}; +struct StateEmptyActive { + std::unique_ptr label; + PixmapSetEmptyActive *pixmaps = nullptr; + bool empty = false; + bool active = false; + + void setActive(bool b) + { + if (!label || b == active) + return; + + active = b; + refresh(); + } + void setEmpty(bool b) + { + if (!label || b == empty) + return; + + empty = b; + refresh(); + } + void refresh() + { + if (!label) + return; + if (empty) { + label->setPixmap(active ? pixmaps->empty_active : pixmaps->empty); + } else { label->setPixmap(active ? pixmaps->active : pixmaps->normal); } - }; - struct StateEmpty { - std::unique_ptr label; - PixmapSetEmpty* pixmaps = nullptr; - bool empty = false; - - void setEmpty(bool e) { - if (!label || e == empty) - return; - empty = e; - - refresh(); - } - - void refresh() { - if (!label) - return; - label->setPixmap(empty ? pixmaps->empty : pixmaps->normal); - } - }; - struct StateEmptyActive { - std::unique_ptr label; - PixmapSetEmptyActive* pixmaps = nullptr; - bool empty = false; - bool active = false; - - void setActive(bool b) { - if (!label || b == active) - return; - - active = b; - refresh(); - } - void setEmpty(bool b) { - if (!label || b == empty) - return; - - empty = b; - refresh(); - } - void refresh() { - if (!label) - return; - if (empty) { - label->setPixmap(active ? pixmaps->empty_active : pixmaps->empty); - } else { - label->setPixmap(active ? pixmaps->active : pixmaps->normal); - } - } - }; - - static QSize pixmap_size(16, 16); - static const QString pixmap_empty = QStringLiteral("_empty"); - static const QString pixmap_active = QStringLiteral("_active"); - static const QString pixmap_empty_active = QStringLiteral("_empty_active"); - void PixmapSetEmpty::load(const QString &basePath) { - normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); - empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); } +}; - void PixmapSetActive::load(const QString &basePath) { - normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); - active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); - } +static QSize pixmap_size(16, 16); +static const QString pixmap_empty = QStringLiteral("_empty"); +static const QString pixmap_active = QStringLiteral("_active"); +static const QString pixmap_empty_active = QStringLiteral("_empty_active"); +void +PixmapSetEmpty::load(const QString &basePath) +{ + normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); + empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); +} - void PixmapSetEmptyActive::load(QString basePath) { - normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); - active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); - empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); - empty_active = ProgSettings::loadIcon(basePath.arg(pixmap_empty_active)).pixmap(pixmap_size); - } +void +PixmapSetActive::load(const QString &basePath) +{ + normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); + active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); +} + +void +PixmapSetEmptyActive::load(QString basePath) +{ + normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); + active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); + empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); + empty_active = ProgSettings::loadIcon(basePath.arg(pixmap_empty_active)).pixmap(pixmap_size); +} } struct MachineStatus::States { Pixmaps pixmaps; - States(QObject* parent) { + States(QObject *parent) + { pixmaps.cartridge.load("/cartridge%1.ico"); pixmaps.cassette.load("/cassette%1.ico"); - pixmaps.floppy_disabled.normal = ProgSettings::loadIcon(QStringLiteral("/floppy_disabled.ico")).pixmap(pixmap_size); - pixmaps.floppy_disabled.active = pixmaps.floppy_disabled.normal; - pixmaps.floppy_disabled.empty = pixmaps.floppy_disabled.normal; + pixmaps.floppy_disabled.normal = ProgSettings::loadIcon(QStringLiteral("/floppy_disabled.ico")).pixmap(pixmap_size); + pixmaps.floppy_disabled.active = pixmaps.floppy_disabled.normal; + pixmaps.floppy_disabled.empty = pixmaps.floppy_disabled.normal; pixmaps.floppy_disabled.empty_active = pixmaps.floppy_disabled.normal; pixmaps.floppy_525.load("/floppy_525%1.ico"); pixmaps.floppy_35.load("/floppy_35%1.ico"); @@ -204,42 +218,42 @@ struct MachineStatus::States { cartridge[0].pixmaps = &pixmaps.cartridge; cartridge[1].pixmaps = &pixmaps.cartridge; - cassette.pixmaps = &pixmaps.cassette; - for (auto& f : fdd) { + cassette.pixmaps = &pixmaps.cassette; + for (auto &f : fdd) { f.pixmaps = &pixmaps.floppy_disabled; } - for (auto& c : cdrom) { + for (auto &c : cdrom) { c.pixmaps = &pixmaps.cdrom; } - for (auto& z : zip) { + for (auto &z : zip) { z.pixmaps = &pixmaps.zip; } - for (auto& m : mo) { + for (auto &m : mo) { m.pixmaps = &pixmaps.mo; } - for (auto& h : hdds) { + for (auto &h : hdds) { h.pixmaps = &pixmaps.hd; } - for (auto& n : net) { + for (auto &n : net) { n.pixmaps = &pixmaps.net; } } - std::array cartridge; - StateEmptyActive cassette; - std::array fdd; - std::array cdrom; - std::array zip; - std::array mo; - std::array hdds; + std::array cartridge; + StateEmptyActive cassette; + std::array fdd; + std::array cdrom; + std::array zip; + std::array mo; + std::array hdds; std::array net; - std::unique_ptr sound; - std::unique_ptr text; + std::unique_ptr sound; + std::unique_ptr text; }; -MachineStatus::MachineStatus(QObject *parent) : - QObject(parent), - refreshTimer(new QTimer(this)) +MachineStatus::MachineStatus(QObject *parent) + : QObject(parent) + , refreshTimer(new QTimer(this)) { d = std::make_unique(this); connect(refreshTimer, &QTimer::timeout, this, &MachineStatus::refreshIcons); @@ -248,19 +262,27 @@ MachineStatus::MachineStatus(QObject *parent) : MachineStatus::~MachineStatus() = default; -bool MachineStatus::hasCassette() { +bool +MachineStatus::hasCassette() +{ return cassette_enable > 0 ? true : false; } -bool MachineStatus::hasIDE() { +bool +MachineStatus::hasIDE() +{ return machine_has_flags(machine, MACHINE_IDE_QUAD) > 0; } -bool MachineStatus::hasSCSI() { +bool +MachineStatus::hasSCSI() +{ return machine_has_flags(machine, MACHINE_SCSI_DUAL) > 0; } -void MachineStatus::iterateFDD(const std::function &cb) { +void +MachineStatus::iterateFDD(const std::function &cb) +{ for (int i = 0; i < FDD_NUM; ++i) { if (fdd_get_type(i) != 0) { cb(i); @@ -268,17 +290,15 @@ void MachineStatus::iterateFDD(const std::function &cb) { } } -void MachineStatus::iterateCDROM(const std::function &cb) { +void +MachineStatus::iterateCDROM(const std::function &cb) +{ auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < CDROM_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && - !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && - hdc_name.left(5) != QStringLiteral("xtide")) + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) continue; - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && - (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && - (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (cdrom[i].bus_type != 0) { cb(i); @@ -286,17 +306,15 @@ void MachineStatus::iterateCDROM(const std::function &cb) { } } -void MachineStatus::iterateZIP(const std::function &cb) { +void +MachineStatus::iterateZIP(const std::function &cb) +{ auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < ZIP_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && - !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && - hdc_name.left(5) != QStringLiteral("xtide")) + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) continue; - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && - (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && - (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (zip_drives[i].bus_type != 0) { cb(i); @@ -304,17 +322,15 @@ void MachineStatus::iterateZIP(const std::function &cb) { } } -void MachineStatus::iterateMO(const std::function &cb) { +void +MachineStatus::iterateMO(const std::function &cb) +{ auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < MO_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && - !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && - hdc_name.left(5) != QStringLiteral("xtide")) + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) continue; - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() && - (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && - (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (mo_drives[i].bus_type != 0) { cb(i); @@ -322,7 +338,9 @@ void MachineStatus::iterateMO(const std::function &cb) { } } -void MachineStatus::iterateNIC(const std::function &cb) { +void +MachineStatus::iterateNIC(const std::function &cb) +{ for (int i = 0; i < NET_CARD_MAX; i++) { if (network_dev_available(i)) { cb(i); @@ -330,7 +348,9 @@ void MachineStatus::iterateNIC(const std::function &cb) { } } -static int hdd_count(int bus) { +static int +hdd_count(int bus) +{ int c = 0; int i; @@ -340,10 +360,12 @@ static int hdd_count(int bus) { } } - return(c); + return (c); } -void MachineStatus::refreshIcons() { +void +MachineStatus::refreshIcons() +{ for (size_t i = 0; i < FDD_NUM; ++i) { d->fdd[i].setActive(machine_status.fdd[i].active); d->fdd[i].setEmpty(machine_status.fdd[i].empty); @@ -375,18 +397,19 @@ void MachineStatus::refreshIcons() { for (int i = 0; i < 2; ++i) { d->cartridge[i].setEmpty(machine_status.cartridge[i].empty); } - } -void MachineStatus::refresh(QStatusBar* sbar) { - bool has_mfm = machine_has_flags(machine, MACHINE_MFM) > 0; - bool has_xta = machine_has_flags(machine, MACHINE_XTA) > 0; +void +MachineStatus::refresh(QStatusBar *sbar) +{ + bool has_mfm = machine_has_flags(machine, MACHINE_MFM) > 0; + bool has_xta = machine_has_flags(machine, MACHINE_XTA) > 0; bool has_esdi = machine_has_flags(machine, MACHINE_ESDI) > 0; - int c_mfm = hdd_count(HDD_BUS_MFM); + int c_mfm = hdd_count(HDD_BUS_MFM); int c_esdi = hdd_count(HDD_BUS_ESDI); - int c_xta = hdd_count(HDD_BUS_XTA); - int c_ide = hdd_count(HDD_BUS_IDE); + int c_xta = hdd_count(HDD_BUS_XTA); + int c_ide = hdd_count(HDD_BUS_IDE); int c_scsi = hdd_count(HDD_BUS_SCSI); sbar->removeWidget(d->cassette.label.get()); @@ -417,10 +440,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->cassette.label = std::make_unique(); d->cassette.setEmpty(QString(cassette_fname).isEmpty()); d->cassette.refresh(); - connect((ClickableLabel*)d->cassette.label.get(), &ClickableLabel::clicked, [](QPoint pos) { + connect((ClickableLabel *) d->cassette.label.get(), &ClickableLabel::clicked, [](QPoint pos) { MediaMenu::ptr->cassetteMenu->popup(pos - QPoint(0, MediaMenu::ptr->cassetteMenu->sizeHint().height())); }); - connect((ClickableLabel*)d->cassette.label.get(), &ClickableLabel::dropped, [](QString str) { + connect((ClickableLabel *) d->cassette.label.get(), &ClickableLabel::dropped, [](QString str) { MediaMenu::ptr->cassetteMount(str, false); }); d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); @@ -433,10 +456,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->cartridge[i].label = std::make_unique(); d->cartridge[i].setEmpty(QString(cart_fns[i]).isEmpty()); d->cartridge[i].refresh(); - connect((ClickableLabel*)d->cartridge[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->cartridge[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->cartridgeMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->cartridgeMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->cartridge[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->cartridge[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->cartridgeMount(i, str); }); d->cartridge[i].label->setToolTip(MediaMenu::ptr->cartridgeMenus[i]->title()); @@ -458,10 +481,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->fdd[i].setEmpty(QString(floppyfns[i]).isEmpty()); d->fdd[i].setActive(false); d->fdd[i].refresh(); - connect((ClickableLabel*)d->fdd[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->fdd[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->floppyMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->floppyMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->fdd[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->fdd[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->floppyMount(i, str, false); }); d->fdd[i].label->setToolTip(MediaMenu::ptr->floppyMenus[i]->title()); @@ -474,10 +497,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->cdrom[i].setEmpty(cdrom[i].host_drive != 200 || QString(cdrom[i].image_path).isEmpty()); d->cdrom[i].setActive(false); d->cdrom[i].refresh(); - connect((ClickableLabel*)d->cdrom[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->cdrom[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->cdromMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->cdromMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->cdrom[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->cdrom[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->cdromMount(i, str); }); d->cdrom[i].label->setToolTip(MediaMenu::ptr->cdromMenus[i]->title()); @@ -490,10 +513,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->zip[i].setEmpty(QString(zip_drives[i].image_path).isEmpty()); d->zip[i].setActive(false); d->zip[i].refresh(); - connect((ClickableLabel*)d->zip[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->zip[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->zipMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->zipMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->zip[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->zip[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->zipMount(i, str, false); }); d->zip[i].label->setToolTip(MediaMenu::ptr->zipMenus[i]->title()); @@ -506,10 +529,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty()); d->mo[i].setActive(false); d->mo[i].refresh(); - connect((ClickableLabel*)d->mo[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->mo[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->moMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->moMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->mo[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->mo[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->moMount(i, str, false); }); d->mo[i].label->setToolTip(MediaMenu::ptr->moMenus[i]->title()); @@ -523,7 +546,7 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->net[i].setActive(false); d->net[i].refresh(); d->net[i].label->setToolTip(MediaMenu::ptr->netMenus[i]->title()); - connect((ClickableLabel*)d->net[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->net[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->netMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->netMenus[i]->sizeHint().height())); }); sbar->addWidget(d->net[i].label.get()); @@ -558,8 +581,7 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->hdds[HDD_BUS_IDE].label->setToolTip(tr("Hard disk (%s)").replace("%s", "IDE")); sbar->addWidget(d->hdds[HDD_BUS_IDE].label.get()); } - if ((hasSCSI() || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || - (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && c_scsi > 0) { + if ((hasSCSI() || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && c_scsi > 0) { d->hdds[HDD_BUS_SCSI].label = std::make_unique(); d->hdds[HDD_BUS_SCSI].setActive(false); d->hdds[HDD_BUS_SCSI].refresh(); @@ -580,45 +602,57 @@ void MachineStatus::refresh(QStatusBar* sbar) { sbar->addWidget(d->text.get()); } -void MachineStatus::message(const QString &msg) { +void +MachineStatus::message(const QString &msg) +{ d->text->setText(msg); } -QString MachineStatus::getMessage() { +QString +MachineStatus::getMessage() +{ return d->text->text(); } -void MachineStatus::updateTip(int tag) +void +MachineStatus::updateTip(int tag) { int category = tag & 0xfffffff0; - int item = tag & 0xf; - if (!MediaMenu::ptr) return; + int item = tag & 0xf; + if (!MediaMenu::ptr) + return; switch (category) { - case SB_CASSETTE: - if (d->cassette.label && MediaMenu::ptr->cassetteMenu) d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); - break; - case SB_CARTRIDGE: - if (d->cartridge[item].label && MediaMenu::ptr->cartridgeMenus[item]) d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title()); - break; - case SB_FLOPPY: - if (d->fdd[item].label && MediaMenu::ptr->floppyMenus[item]) d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title()); - break; - case SB_CDROM: - if (d->cdrom[item].label && MediaMenu::ptr->cdromMenus[item]) d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title()); - break; - case SB_ZIP: - if (d->zip[item].label && MediaMenu::ptr->zipMenus[item]) d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title()); - break; - case SB_MO: - if (d->mo[item].label && MediaMenu::ptr->moMenus[item]) d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title()); - break; - case SB_HDD: - break; - case SB_NETWORK: - break; - case SB_SOUND: - break; - case SB_TEXT: - break; + case SB_CASSETTE: + if (d->cassette.label && MediaMenu::ptr->cassetteMenu) + d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); + break; + case SB_CARTRIDGE: + if (d->cartridge[item].label && MediaMenu::ptr->cartridgeMenus[item]) + d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title()); + break; + case SB_FLOPPY: + if (d->fdd[item].label && MediaMenu::ptr->floppyMenus[item]) + d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title()); + break; + case SB_CDROM: + if (d->cdrom[item].label && MediaMenu::ptr->cdromMenus[item]) + d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title()); + break; + case SB_ZIP: + if (d->zip[item].label && MediaMenu::ptr->zipMenus[item]) + d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title()); + break; + case SB_MO: + if (d->mo[item].label && MediaMenu::ptr->moMenus[item]) + d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title()); + break; + case SB_HDD: + break; + case SB_NETWORK: + break; + case SB_SOUND: + break; + case SB_TEXT: + break; } } diff --git a/src/qt/qt_machinestatus.hpp b/src/qt/qt_machinestatus.hpp index 8d085f93a..c2e51819a 100644 --- a/src/qt/qt_machinestatus.hpp +++ b/src/qt/qt_machinestatus.hpp @@ -12,47 +12,48 @@ class QStatusBar; class ClickableLabel : public QLabel { Q_OBJECT; - public: - explicit ClickableLabel(QWidget* parent = nullptr) - : QLabel(parent) {} - ~ClickableLabel() {}; - signals: - void clicked(QPoint); - void doubleClicked(QPoint); - void dropped(QString); +public: + explicit ClickableLabel(QWidget *parent = nullptr) + : QLabel(parent) + { + } + ~ClickableLabel() {}; - protected: - void mousePressEvent(QMouseEvent* event) override { emit clicked(event->globalPos()); } - void mouseDoubleClickEvent(QMouseEvent* event) override { emit doubleClicked(event->globalPos()); } - void dragEnterEvent(QDragEnterEvent* event) override - { - if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { - event->setDropAction(Qt::CopyAction); - event->acceptProposedAction(); - } - else event->ignore(); - } - void dragMoveEvent(QDragMoveEvent* event) override - { - if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { - event->setDropAction(Qt::CopyAction); - event->acceptProposedAction(); - } - else event->ignore(); - } - void dropEvent(QDropEvent* event) override - { - if (event->dropAction() == Qt::CopyAction) - { - emit dropped(event->mimeData()->urls()[0].toLocalFile()); - } - else event->ignore(); - } +signals: + void clicked(QPoint); + void doubleClicked(QPoint); + void dropped(QString); + +protected: + void mousePressEvent(QMouseEvent *event) override { emit clicked(event->globalPos()); } + void mouseDoubleClickEvent(QMouseEvent *event) override { emit doubleClicked(event->globalPos()); } + void dragEnterEvent(QDragEnterEvent *event) override + { + if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { + event->setDropAction(Qt::CopyAction); + event->acceptProposedAction(); + } else + event->ignore(); + } + void dragMoveEvent(QDragMoveEvent *event) override + { + if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { + event->setDropAction(Qt::CopyAction); + event->acceptProposedAction(); + } else + event->ignore(); + } + void dropEvent(QDropEvent *event) override + { + if (event->dropAction() == Qt::CopyAction) { + emit dropped(event->mimeData()->urls()[0].toLocalFile()); + } else + event->ignore(); + } }; -class MachineStatus : public QObject -{ +class MachineStatus : public QObject { Q_OBJECT public: @@ -62,23 +63,23 @@ public: static bool hasCassette(); static bool hasIDE(); static bool hasSCSI(); - static void iterateFDD(const std::function& cb); - static void iterateCDROM(const std::function& cb); - static void iterateZIP(const std::function& cb); - static void iterateMO(const std::function& cb); - static void iterateNIC(const std::function& cb); + static void iterateFDD(const std::function &cb); + static void iterateCDROM(const std::function &cb); + static void iterateZIP(const std::function &cb); + static void iterateMO(const std::function &cb); + static void iterateNIC(const std::function &cb); QString getMessage(); public slots: - void refresh(QStatusBar* sbar); - void message(const QString& msg); + void refresh(QStatusBar *sbar); + void message(const QString &msg); void updateTip(int tag); void refreshIcons(); private: struct States; std::unique_ptr d; - QTimer *refreshTimer; + QTimer *refreshTimer; }; #endif // QT_MACHINESTATUS_HPP diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 6f471dc53..1ae545227 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -31,23 +31,22 @@ #ifdef QT_STATIC /* Static builds need plugin imports */ -#include +# include Q_IMPORT_PLUGIN(QICOPlugin) -#ifdef Q_OS_WINDOWS +# ifdef Q_OS_WINDOWS Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) -#endif +# endif #endif #ifdef Q_OS_WINDOWS -#include "qt_winrawinputfilter.hpp" -#include "qt_winmanagerfilter.hpp" -#include <86box/win.h> -#include +# include "qt_winrawinputfilter.hpp" +# include "qt_winmanagerfilter.hpp" +# include <86box/win.h> +# include #endif -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/config.h> #include <86box/plat.h> @@ -69,15 +68,15 @@ extern "C" #include "qt_unixmanagerfilter.hpp" // Void Cast -#define VC(x) const_cast(x) +#define VC(x) const_cast(x) extern QElapsedTimer elapsed_timer; -extern MainWindow* main_window; +extern MainWindow *main_window; extern "C" { #include <86box/timer.h> #include <86box/nvr.h> - extern int qt_nvr_save(void); +extern int qt_nvr_save(void); } void qt_set_sequence_auto_mnemonic(bool b); @@ -86,11 +85,11 @@ void main_thread_fn() { uint64_t old_time, new_time; - int drawits, frames; + int drawits, frames; QThread::currentThread()->setPriority(QThread::HighestPriority); framecountx = 0; - //title_update = 1; + // title_update = 1; old_time = elapsed_timer.elapsed(); drawits = frames = 0; while (!is_quit && cpu_thread_run) { @@ -98,10 +97,10 @@ main_thread_fn() new_time = elapsed_timer.elapsed(); #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) - drawits = 10; + drawits = 10; else #endif - drawits += (new_time - old_time); + drawits += (new_time - old_time); old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ @@ -117,8 +116,8 @@ main_thread_fn() #ifdef USE_INSTRUMENT if (instru_enabled) { - uint64_t elapsed_us = (elapsed_timer.nsecsElapsed() - start_time) / 1000; - uint64_t total_elapsed_ms = (uint64_t)((double)tsc / cpu_s->rspeed * 1000); + uint64_t elapsed_us = (elapsed_timer.nsecsElapsed() - start_time) / 1000; + uint64_t total_elapsed_ms = (uint64_t) ((double) tsc / cpu_s->rspeed * 1000); printf("[instrument] %llu, %llu\n", total_elapsed_ms, elapsed_us); if (instru_run_ms && total_elapsed_ms >= instru_run_ms) break; @@ -128,7 +127,7 @@ main_thread_fn() if (++frames >= 200 && nvr_dosave) { qt_nvr_save(); nvr_dosave = 0; - frames = 0; + frames = 0; } } else { /* Just so we dont overload the host OS. */ @@ -137,12 +136,14 @@ main_thread_fn() } is_quit = 1; - QTimer::singleShot(0, QApplication::instance(), [] () { QApplication::instance()->quit(); }); + QTimer::singleShot(0, QApplication::instance(), []() { QApplication::instance()->quit(); }); } -static std::thread* main_thread; +static std::thread *main_thread; -int main(int argc, char* argv[]) { +int +main(int argc, char *argv[]) +{ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); @@ -168,8 +169,7 @@ int main(int argc, char* argv[]) { #endif elapsed_timer.start(); - if (!pc_init(argc, argv)) - { + if (!pc_init(argc, argv)) { return 0; } @@ -182,16 +182,14 @@ int main(int argc, char* argv[]) { QApplication::setFont(QFont(font_name, font_size.toInt())); SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif - if (! pc_init_modules()) { - ui_msgbox_header(MBX_FATAL, (void*)IDS_2120, (void*)IDS_2056); + if (!pc_init_modules()) { + ui_msgbox_header(MBX_FATAL, (void *) IDS_2121, (void *) IDS_2056); return 6; } - if (settings_only) - { + if (settings_only) { Settings settings; - if (settings.exec() == QDialog::Accepted) - { + if (settings.exec() == QDialog::Accepted) { settings.save(); config_save(); } @@ -212,22 +210,21 @@ int main(int argc, char* argv[]) { #ifdef Q_OS_WINDOWS /* Setup VM-manager messages */ std::unique_ptr wmfilter; - if (source_hwnd) - { - HWND main_hwnd = (HWND)main_window->winId(); + if (source_hwnd) { + HWND main_hwnd = (HWND) main_window->winId(); wmfilter.reset(new WindowsManagerFilter()); QObject::connect(wmfilter.get(), &WindowsManagerFilter::showsettings, main_window, &MainWindow::showSettings); QObject::connect(wmfilter.get(), &WindowsManagerFilter::pause, main_window, &MainWindow::togglePause); QObject::connect(wmfilter.get(), &WindowsManagerFilter::reset, main_window, &MainWindow::hardReset); QObject::connect(wmfilter.get(), &WindowsManagerFilter::request_shutdown, main_window, &MainWindow::close); - QObject::connect(wmfilter.get(), &WindowsManagerFilter::force_shutdown, [](){ + QObject::connect(wmfilter.get(), &WindowsManagerFilter::force_shutdown, []() { do_stop(); emit main_window->close(); }); - QObject::connect(wmfilter.get(), &WindowsManagerFilter::ctrlaltdel, [](){ pc_send_cad(); }); - QObject::connect(wmfilter.get(), &WindowsManagerFilter::dialogstatus, [main_hwnd](bool open){ - PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDDLGSTATUS, (WPARAM)(open ? 1 : 0), (LPARAM)main_hwnd); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::ctrlaltdel, []() { pc_send_cad(); }); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::dialogstatus, [main_hwnd](bool open) { + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) (open ? 1 : 0), (LPARAM) main_hwnd); }); /* Native filter to catch VM-managers commands */ @@ -237,41 +234,39 @@ int main(int argc, char* argv[]) { main_window->installEventFilter(wmfilter.get()); /* Send main window HWND to manager */ - PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDHWND, (WPARAM)unique_id, (LPARAM)main_hwnd); + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDHWND, (WPARAM) unique_id, (LPARAM) main_hwnd); /* Send shutdown message to manager */ - QObject::connect(&app, &QApplication::destroyed, [main_hwnd](QObject*) { - PostMessage((HWND)(uintptr_t)source_hwnd, WM_HAS_SHUTDOWN, (WPARAM)0, (LPARAM)main_hwnd); + QObject::connect(&app, &QApplication::destroyed, [main_hwnd](QObject *) { + PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) main_hwnd); }); } /* Setup raw input */ auto rawInputFilter = WindowsRawInputFilter::Register(main_window); - if (rawInputFilter) - { + if (rawInputFilter) { app.installNativeEventFilter(rawInputFilter.get()); QObject::disconnect(main_window, &MainWindow::pollMouse, 0, 0); - QObject::connect(main_window, &MainWindow::pollMouse, (WindowsRawInputFilter*)rawInputFilter.get(), &WindowsRawInputFilter::mousePoll, Qt::DirectConnection); + QObject::connect(main_window, &MainWindow::pollMouse, (WindowsRawInputFilter *) rawInputFilter.get(), &WindowsRawInputFilter::mousePoll, Qt::DirectConnection); main_window->setSendKeyboardInput(false); } #endif UnixManagerSocket socket; - if (qgetenv("86BOX_MANAGER_SOCKET").size()) - { + if (qgetenv("86BOX_MANAGER_SOCKET").size()) { QObject::connect(&socket, &UnixManagerSocket::showsettings, main_window, &MainWindow::showSettings); QObject::connect(&socket, &UnixManagerSocket::pause, main_window, &MainWindow::togglePause); QObject::connect(&socket, &UnixManagerSocket::resetVM, main_window, &MainWindow::hardReset); QObject::connect(&socket, &UnixManagerSocket::request_shutdown, main_window, &MainWindow::close); - QObject::connect(&socket, &UnixManagerSocket::force_shutdown, [](){ + QObject::connect(&socket, &UnixManagerSocket::force_shutdown, []() { do_stop(); emit main_window->close(); }); - QObject::connect(&socket, &UnixManagerSocket::ctrlaltdel, [](){ pc_send_cad(); }); + QObject::connect(&socket, &UnixManagerSocket::ctrlaltdel, []() { pc_send_cad(); }); main_window->installEventFilter(&socket); socket.connectToServer(qgetenv("86BOX_MANAGER_SOCKET")); } - //pc_reset_hard_init(); + // pc_reset_hard_init(); /* Set the PAUSE mode depending on the renderer. */ // plat_pause(0); @@ -297,13 +292,12 @@ int main(int argc, char* argv[]) { } /* Initialize the rendering window, or fullscreen. */ - QTimer::singleShot(0, &app, [] - { + QTimer::singleShot(0, &app, [] { pc_reset_hard_init(); main_thread = new std::thread(main_thread_fn); }); - auto ret = app.exec(); + auto ret = app.exec(); cpu_thread_run = 0; main_thread->join(); pc_close(nullptr); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 9e81531ab..bf3ef4014 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -47,13 +47,13 @@ extern "C" { #include <86box/version.h> #ifdef USE_VNC -#include <86box/vnc.h> +# include <86box/vnc.h> #endif - extern int qt_nvr_save(void); +extern int qt_nvr_save(void); #ifdef MTR_ENABLED -#include +# include #endif }; @@ -76,8 +76,8 @@ extern "C" { #include #include #if QT_CONFIG(vulkan) -#include -#include +# include +# include #endif #include @@ -89,70 +89,69 @@ extern "C" { #include "qt_util.hpp" #if defined __unix__ && !defined __HAIKU__ -#ifdef WAYLAND -#include "wl_mouse.hpp" -#endif -#include -#include -#undef KeyPress -#undef KeyRelease +# ifdef WAYLAND +# include "wl_mouse.hpp" +# endif +# include +# include +# undef KeyPress +# undef KeyRelease #endif #ifdef Q_OS_MACOS // The namespace is required to avoid clashing typedefs; we only use this // header for its #defines anyway. namespace IOKit { - #include +# include } #endif #ifdef __HAIKU__ -#include -#include +# include +# include -extern MainWindow* main_window; +extern MainWindow *main_window; -filter_result keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) +filter_result +keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) { if (message->what == B_KEY_DOWN || message->what == B_KEY_UP - || message->what == B_UNMAPPED_KEY_DOWN || message->what == B_UNMAPPED_KEY_UP) - { + || message->what == B_UNMAPPED_KEY_DOWN || message->what == B_UNMAPPED_KEY_UP) { int key_state = 0, key_scancode = 0; key_state = message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN; message->FindInt32("key", &key_scancode); QGuiApplication::postEvent(main_window, new QKeyEvent(key_state ? QEvent::KeyPress : QEvent::KeyRelease, 0, QGuiApplication::keyboardModifiers(), key_scancode, 0, 0)); - if (key_scancode == 0x68 && key_state) - { + if (key_scancode == 0x68 && key_state) { QGuiApplication::postEvent(main_window, new QKeyEvent(QEvent::KeyRelease, 0, QGuiApplication::keyboardModifiers(), key_scancode, 0, 0)); } } return B_DISPATCH_MESSAGE; } -static BMessageFilter* filter; +static BMessageFilter *filter; #endif -std::atomic blitDummied{false}; +std::atomic blitDummied { false }; -extern void qt_mouse_capture(int); +extern void qt_mouse_capture(int); extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); -extern MainWindow* main_window; +extern MainWindow *main_window; -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow) +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) { - mm = std::make_shared(this); + mm = std::make_shared(this); MediaMenu::ptr = mm; - status = std::make_unique(this); + status = std::make_unique(this); #ifdef __HAIKU__ filter = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE, keyb_filter); - ((BWindow*)this->winId())->AddFilter(filter); + ((BWindow *) this->winId())->AddFilter(filter); #endif setUnifiedTitleAndToolBarOnMac(true); - extern MainWindow* main_window; + extern MainWindow *main_window; main_window = this; ui->setupUi(this); ui->stackedWidget->setMouseTracking(true); @@ -160,6 +159,9 @@ MainWindow::MainWindow(QWidget *parent) : statusBar()->setStyleSheet("QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; }"); this->centralWidget()->setStyleSheet("background-color: black;"); ui->toolBar->setVisible(!hide_tool_bar); +#ifdef _WIN32 + ui->toolBar->setBackgroundRole(QPalette::Light); +#endif renderers[0].reset(nullptr); auto toolbar_spacer = new QWidget(); toolbar_spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -181,14 +183,14 @@ MainWindow::MainWindow(QWidget *parent) : this->setWindowFlag(Qt::WindowMaximizeButtonHint, vid_resize == 1); QString vmname(vm_name); - if (vmname.at(vmname.size() - 1) == '"' || vmname.at(vmname.size() - 1) == '\'') vmname.truncate(vmname.size() - 1); + if (vmname.at(vmname.size() - 1) == '"' || vmname.at(vmname.size() - 1) == '\'') + vmname.truncate(vmname.size() - 1); this->setWindowTitle(QString("%1 - %2 %3").arg(vmname, EMU_NAME, EMU_VERSION_FULL)); connect(this, &MainWindow::showMessageForNonQtThread, this, &MainWindow::showMessage_, Qt::BlockingQueuedConnection); - connect(this, &MainWindow::setTitle, this, [this,toolbar_label](const QString& title) { - if (dopause && !hide_tool_bar) - { + connect(this, &MainWindow::setTitle, this, [this, toolbar_label](const QString &title) { + if (dopause && !hide_tool_bar) { toolbar_label->setText(toolbar_label->text() + tr(" - PAUSED")); return; } @@ -247,7 +249,8 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, &MainWindow::resizeContents, this, [this](int w, int h) { if (shownonce) { - if (resizableonce == false) ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + if (resizableonce == false) + ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); resizableonce = true; } if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { @@ -263,8 +266,7 @@ MainWindow::MainWindow(QWidget *parent) : } }); - connect(this, &MainWindow::resizeContentsMonitor, this, [this](int w, int h, int monitor_index) - { + connect(this, &MainWindow::resizeContentsMonitor, this, [this](int w, int h, int monitor_index) { if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { qDebug() << "Resize"; w = (w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); @@ -277,8 +279,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(ui->menubar, &QMenuBar::triggered, this, [this] { config_save(); - if (QApplication::activeWindow() == this) - { + if (QApplication::activeWindow() == this) { ui->stackedWidget->setFocusRenderer(); } }); @@ -306,13 +307,16 @@ MainWindow::MainWindow(QWidget *parent) : #if defined Q_OS_WINDOWS || defined Q_OS_MACOS /* Make the option visible only if ANGLE is loaded. */ ui->actionHardware_Renderer_OpenGL_ES->setVisible(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES); - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) vid_api = 1; + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) + vid_api = 1; #endif ui->actionHardware_Renderer_OpenGL->setVisible(QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES); - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && vid_api == 1) vid_api = 0; + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && vid_api == 1) + vid_api = 0; if ((QApplication::platformName().contains("eglfs") || QApplication::platformName() == "haiku")) { - if (vid_api >= 1) fprintf(stderr, "OpenGL renderers are unsupported on %s.\n", QApplication::platformName().toUtf8().data()); + if (vid_api >= 1) + fprintf(stderr, "OpenGL renderers are unsupported on %s.\n", QApplication::platformName().toUtf8().data()); vid_api = 0; ui->actionHardware_Renderer_OpenGL->setVisible(false); ui->actionHardware_Renderer_OpenGL_ES->setVisible(false); @@ -321,11 +325,13 @@ MainWindow::MainWindow(QWidget *parent) : } #if !defined Q_OS_WINDOWS ui->actionDirect3D_9->setVisible(false); - if (vid_api == 5) vid_api = 0; + if (vid_api == 5) + vid_api = 0; #endif #ifndef USE_VNC - if (vid_api == 6) vid_api = 0; + if (vid_api == 6) + vid_api = 0; ui->actionVNC->setVisible(false); #endif @@ -345,11 +351,12 @@ MainWindow::MainWindow(QWidget *parent) : if (!vulkanAvailable) #endif { - if (vid_api == 4) vid_api = 0; + if (vid_api == 4) + vid_api = 0; ui->actionVulkan->setVisible(false); } - QActionGroup* actGroup = nullptr; + QActionGroup *actGroup = nullptr; actGroup = new QActionGroup(this); actGroup->addAction(ui->actionSoftware_Renderer); @@ -361,7 +368,7 @@ MainWindow::MainWindow(QWidget *parent) : actGroup->addAction(ui->actionVNC); actGroup->setExclusive(true); - connect(actGroup, &QActionGroup::triggered, [this](QAction* action) { + connect(actGroup, &QActionGroup::triggered, [this](QAction *action) { vid_api = action->property("vid_api").toInt(); #ifdef USE_VNC if (vnc_enabled && vid_api != 6) { @@ -373,40 +380,41 @@ MainWindow::MainWindow(QWidget *parent) : } #endif RendererStack::Renderer newVidApi = RendererStack::Renderer::Software; - switch (vid_api) - { - case 0: - newVidApi = RendererStack::Renderer::Software; - break; - case 1: - newVidApi = (RendererStack::Renderer::OpenGL); - break; - case 2: - newVidApi = (RendererStack::Renderer::OpenGLES); - break; - case 3: - newVidApi = (RendererStack::Renderer::OpenGL3); - break; - case 4: - newVidApi = (RendererStack::Renderer::Vulkan); - break; - case 5: - newVidApi = (RendererStack::Renderer::Direct3D9); - break; -#ifdef USE_VNC - case 6: - { + switch (vid_api) { + case 0: newVidApi = RendererStack::Renderer::Software; - startblit(); - vnc_enabled = vnc_init(nullptr); - endblit(); - } + break; + case 1: + newVidApi = (RendererStack::Renderer::OpenGL); + break; + case 2: + newVidApi = (RendererStack::Renderer::OpenGLES); + break; + case 3: + newVidApi = (RendererStack::Renderer::OpenGL3); + break; + case 4: + newVidApi = (RendererStack::Renderer::Vulkan); + break; + case 5: + newVidApi = (RendererStack::Renderer::Direct3D9); + break; +#ifdef USE_VNC + case 6: + { + newVidApi = RendererStack::Renderer::Software; + startblit(); + vnc_enabled = vnc_init(nullptr); + endblit(); + } #endif } ui->stackedWidget->switchRenderer(newVidApi); - if (!show_second_monitors) return; + if (!show_second_monitors) + return; for (int i = 1; i < MONITORS_NUM; i++) { - if (renderers[i]) renderers[i]->switchRenderer(newVidApi); + if (renderers[i]) + renderers[i]->switchRenderer(newVidApi); } }); @@ -423,36 +431,36 @@ MainWindow::MainWindow(QWidget *parent) : } switch (scale) { - case 0: - ui->action0_5x->setChecked(true); - break; - case 1: - ui->action1x->setChecked(true); - break; - case 2: - ui->action1_5x->setChecked(true); - break; - case 3: - ui->action2x->setChecked(true); - break; - case 4: - ui->action3x->setChecked(true); - break; - case 5: - ui->action4x->setChecked(true); - break; - case 6: - ui->action5x->setChecked(true); - break; - case 7: - ui->action6x->setChecked(true); - break; - case 8: - ui->action7x->setChecked(true); - break; - case 9: - ui->action8x->setChecked(true); - break; + case 0: + ui->action0_5x->setChecked(true); + break; + case 1: + ui->action1x->setChecked(true); + break; + case 2: + ui->action1_5x->setChecked(true); + break; + case 3: + ui->action2x->setChecked(true); + break; + case 4: + ui->action3x->setChecked(true); + break; + case 5: + ui->action4x->setChecked(true); + break; + case 6: + ui->action5x->setChecked(true); + break; + case 7: + ui->action6x->setChecked(true); + break; + case 8: + ui->action7x->setChecked(true); + break; + case 9: + ui->action8x->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->action0_5x); @@ -466,29 +474,29 @@ MainWindow::MainWindow(QWidget *parent) : actGroup->addAction(ui->action7x); actGroup->addAction(ui->action8x); switch (video_filter_method) { - case 0: - ui->actionNearest->setChecked(true); - break; - case 1: - ui->actionLinear->setChecked(true); - break; + case 0: + ui->actionNearest->setChecked(true); + break; + case 1: + ui->actionLinear->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->actionNearest); actGroup->addAction(ui->actionLinear); switch (video_fullscreen_scale) { - case FULLSCR_SCALE_FULL: - ui->actionFullScreen_stretch->setChecked(true); - break; - case FULLSCR_SCALE_43: - ui->actionFullScreen_43->setChecked(true); - break; - case FULLSCR_SCALE_KEEPRATIO: - ui->actionFullScreen_keepRatio->setChecked(true); - break; - case FULLSCR_SCALE_INT: - ui->actionFullScreen_int->setChecked(true); - break; + case FULLSCR_SCALE_FULL: + ui->actionFullScreen_stretch->setChecked(true); + break; + case FULLSCR_SCALE_43: + ui->actionFullScreen_43->setChecked(true); + break; + case FULLSCR_SCALE_KEEPRATIO: + ui->actionFullScreen_keepRatio->setChecked(true); + break; + case FULLSCR_SCALE_INT: + ui->actionFullScreen_int->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->actionFullScreen_stretch); @@ -496,21 +504,21 @@ MainWindow::MainWindow(QWidget *parent) : actGroup->addAction(ui->actionFullScreen_keepRatio); actGroup->addAction(ui->actionFullScreen_int); switch (video_grayscale) { - case 0: - ui->actionRGB_Color->setChecked(true); - break; - case 1: - ui->actionRGB_Grayscale->setChecked(true); - break; - case 2: - ui->actionAmber_monitor->setChecked(true); - break; - case 3: - ui->actionGreen_monitor->setChecked(true); - break; - case 4: - ui->actionWhite_monitor->setChecked(true); - break; + case 0: + ui->actionRGB_Color->setChecked(true); + break; + case 1: + ui->actionRGB_Grayscale->setChecked(true); + break; + case 2: + ui->actionAmber_monitor->setChecked(true); + break; + case 3: + ui->actionGreen_monitor->setChecked(true); + break; + case 4: + ui->actionWhite_monitor->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->actionRGB_Grayscale); @@ -519,15 +527,15 @@ MainWindow::MainWindow(QWidget *parent) : actGroup->addAction(ui->actionWhite_monitor); actGroup->addAction(ui->actionRGB_Color); switch (video_graytype) { - case 0: - ui->actionBT601_NTSC_PAL->setChecked(true); - break; - case 1: - ui->actionBT709_HDTV->setChecked(true); - break; - case 2: - ui->actionAverage->setChecked(true); - break; + case 0: + ui->actionBT601_NTSC_PAL->setChecked(true); + break; + case 1: + ui->actionBT709_HDTV->setChecked(true); + break; + case 2: + ui->actionAverage->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->actionBT601_NTSC_PAL); @@ -548,7 +556,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionCtrl_Alt_Del->setShortcutVisibleInContextMenu(true); ui->actionTake_screenshot->setShortcutVisibleInContextMenu(true); #endif - if (!vnc_enabled) video_setblit(qt_blit); + if (!vnc_enabled) + video_setblit(qt_blit); #ifdef MTR_ENABLED { @@ -557,32 +566,30 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionBegin_trace->setShortcut(QKeySequence(Qt::Key_Control + Qt::Key_T)); ui->actionEnd_trace->setShortcut(QKeySequence(Qt::Key_Control + Qt::Key_T)); ui->actionEnd_trace->setDisabled(true); - static auto init_trace = [&] - { + static auto init_trace = [&] { mtr_init("trace.json"); mtr_start(); }; - static auto shutdown_trace = [&] - { + static auto shutdown_trace = [&] { mtr_stop(); mtr_shutdown(); }; -#ifdef Q_OS_MACOS +# ifdef Q_OS_MACOS ui->actionBegin_trace->setShortcutVisibleInContextMenu(true); ui->actionEnd_trace->setShortcutVisibleInContextMenu(true); -#endif +# endif static bool trace = false; - connect(ui->actionBegin_trace, &QAction::triggered, this, [this] - { - if (trace) return; + connect(ui->actionBegin_trace, &QAction::triggered, this, [this] { + if (trace) + return; ui->actionBegin_trace->setDisabled(true); ui->actionEnd_trace->setDisabled(false); init_trace(); trace = true; }); - connect(ui->actionEnd_trace, &QAction::triggered, this, [this] - { - if (!trace) return; + connect(ui->actionEnd_trace, &QAction::triggered, this, [this] { + if (!trace) + return; ui->actionBegin_trace->setDisabled(false); ui->actionEnd_trace->setDisabled(true); shutdown_trace(); @@ -599,33 +606,34 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, &MainWindow::destroyRendererMonitorForNonQtThread, this, &MainWindow::destroyRendererMonitorSlot, Qt::BlockingQueuedConnection); #ifdef Q_OS_MACOS - QTimer::singleShot(0, this, [this] () { - for (auto curObj : this->menuBar()->children()) { - if (qobject_cast(curObj)) { - auto menu = qobject_cast(curObj); - menu->setSeparatorsCollapsible(false); - for (auto curObj2 : menu->children()) { - if (qobject_cast(curObj2)) { - auto menu2 = qobject_cast(curObj2); - menu2->setSeparatorsCollapsible(false); - } - } - } - } - }); + QTimer::singleShot(0, this, [this]() { + for (auto curObj : this->menuBar()->children()) { + if (qobject_cast(curObj)) { + auto menu = qobject_cast(curObj); + menu->setSeparatorsCollapsible(false); + for (auto curObj2 : menu->children()) { + if (qobject_cast(curObj2)) { + auto menu2 = qobject_cast(curObj2); + menu2->setSeparatorsCollapsible(false); + } + } + } + } + }); #endif } -void MainWindow::closeEvent(QCloseEvent *event) { +void +MainWindow::closeEvent(QCloseEvent *event) +{ if (mouse_capture) { event->ignore(); return; } - if (confirm_exit && confirm_exit_cmdl && cpu_thread_run) - { + if (confirm_exit && confirm_exit_cmdl && cpu_thread_run) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to exit 86Box?"), QMessageBox::Yes | QMessageBox::No, this); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_exit); @@ -650,7 +658,8 @@ void MainWindow::closeEvent(QCloseEvent *event) { if (renderers[i]) { monitor_settings[i].mon_window_w = renderers[i]->geometry().width(); monitor_settings[i].mon_window_h = renderers[i]->geometry().height(); - if (QApplication::platformName().contains("wayland")) continue; + if (QApplication::platformName().contains("wayland")) + continue; monitor_settings[i].mon_window_x = renderers[i]->geometry().x(); monitor_settings[i].mon_window_y = renderers[i]->geometry().y(); } @@ -669,13 +678,13 @@ void MainWindow::closeEvent(QCloseEvent *event) { event->accept(); } -void MainWindow::initRendererMonitorSlot(int monitor_index) +void +MainWindow::initRendererMonitorSlot(int monitor_index) { - auto& secondaryRenderer = this->renderers[monitor_index]; + auto &secondaryRenderer = this->renderers[monitor_index]; secondaryRenderer.reset(new RendererStack(nullptr, monitor_index)); if (secondaryRenderer) { - connect(secondaryRenderer.get(), &RendererStack::rendererChanged, this, [this, monitor_index] - { + connect(secondaryRenderer.get(), &RendererStack::rendererChanged, this, [this, monitor_index] { this->renderers[monitor_index]->show(); }); secondaryRenderer->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); @@ -689,20 +698,20 @@ void MainWindow::initRendererMonitorSlot(int monitor_index) secondaryRenderer->show(); if (window_remember) { secondaryRenderer->setGeometry(monitor_settings[monitor_index].mon_window_x < 120 ? 120 : monitor_settings[monitor_index].mon_window_x, - monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y, - monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, - monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); + monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y, + monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, + monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); } if (monitor_settings[monitor_index].mon_window_maximized) { secondaryRenderer->showMaximized(); } - secondaryRenderer->switchRenderer((RendererStack::Renderer)vid_api); + secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); } - } } -void MainWindow::destroyRendererMonitorSlot(int monitor_index) +void +MainWindow::destroyRendererMonitorSlot(int monitor_index) { if (this->renderers[monitor_index]) { if (window_remember) { @@ -716,26 +725,29 @@ void MainWindow::destroyRendererMonitorSlot(int monitor_index) } } -MainWindow::~MainWindow() { +MainWindow::~MainWindow() +{ delete ui; } -void MainWindow::showEvent(QShowEvent *event) { - if (shownonce) return; +void +MainWindow::showEvent(QShowEvent *event) +{ + if (shownonce) + return; shownonce = true; if (window_remember) { - if (window_w == 0) window_w = 320; - if (window_h == 0) window_h = 200; + if (window_w == 0) + window_w = 320; + if (window_h == 0) + window_h = 200; } if (window_remember && !QApplication::platformName().contains("wayland")) { setGeometry(window_x, window_y, window_w, window_h + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); } if (vid_resize == 2) { - setFixedSize(fixed_size_x, fixed_size_y - + menuBar()->height() - + (hide_status_bar ? 0 : statusBar()->height()) - + (hide_tool_bar ? 0 : ui->toolBar->height())); + setFixedSize(fixed_size_x, fixed_size_y + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); monitors[0].mon_scrnsz_x = fixed_size_x; monitors[0].mon_scrnsz_y = fixed_size_y; @@ -751,17 +763,22 @@ void MainWindow::showEvent(QShowEvent *event) { } } -void MainWindow::on_actionKeyboard_requires_capture_triggered() { +void +MainWindow::on_actionKeyboard_requires_capture_triggered() +{ kbd_req_capture ^= 1; } -void MainWindow::on_actionRight_CTRL_is_left_ALT_triggered() { +void +MainWindow::on_actionRight_CTRL_is_left_ALT_triggered() +{ rctrl_is_lalt ^= 1; } -void MainWindow::on_actionHard_Reset_triggered() { - if (confirm_reset) - { +void +MainWindow::on_actionHard_Reset_triggered() +{ + if (confirm_reset) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to hard reset the emulated machine?"), QMessageBox::NoButton, this); questionbox.addButton(tr("Reset"), QMessageBox::AcceptRole); questionbox.addButton(tr("Don't reset"), QMessageBox::RejectRole); @@ -773,8 +790,7 @@ void MainWindow::on_actionHard_Reset_triggered() { confirm_reset = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); - if (questionbox.result() == QDialog::Accepted) - { + if (questionbox.result() == QDialog::Accepted) { confirm_reset = true; return; } @@ -783,23 +799,33 @@ void MainWindow::on_actionHard_Reset_triggered() { pc_reset_hard(); } -void MainWindow::on_actionCtrl_Alt_Del_triggered() { +void +MainWindow::on_actionCtrl_Alt_Del_triggered() +{ pc_send_cad(); } -void MainWindow::on_actionCtrl_Alt_Esc_triggered() { +void +MainWindow::on_actionCtrl_Alt_Esc_triggered() +{ pc_send_cae(); } -void MainWindow::on_actionPause_triggered() { +void +MainWindow::on_actionPause_triggered() +{ plat_pause(dopause ^ 1); } -void MainWindow::on_actionExit_triggered() { +void +MainWindow::on_actionExit_triggered() +{ close(); } -void MainWindow::on_actionSettings_triggered() { +void +MainWindow::on_actionSettings_triggered() +{ int currentPause = dopause; plat_pause(1); Settings settings(this); @@ -808,27 +834,26 @@ void MainWindow::on_actionSettings_triggered() { settings.exec(); switch (settings.result()) { - case QDialog::Accepted: - /* - pc_reset_hard_close(); - settings.save(); - config_changed = 2; - pc_reset_hard_init(); - */ - settings.save(); - config_changed = 2; - pc_reset_hard(); + case QDialog::Accepted: + /* + pc_reset_hard_close(); + settings.save(); + config_changed = 2; + pc_reset_hard_init(); + */ + settings.save(); + config_changed = 2; + pc_reset_hard(); - break; - case QDialog::Rejected: - break; + break; + case QDialog::Rejected: + break; } plat_pause(currentPause); } #if defined(__unix__) && !defined(__HAIKU__) -std::array x11_to_xt_base -{ +std::array x11_to_xt_base { 0, 0, 0, @@ -950,8 +975,7 @@ std::array x11_to_xt_base 0x15D, }; -std::array x11_to_xt_2 -{ +std::array x11_to_xt_2 { 0, 0, 0, @@ -1090,8 +1114,7 @@ std::array x11_to_xt_2 0x15D }; -std::array x11_to_xt_vnc -{ +std::array x11_to_xt_vnc { 0, 0, 0, @@ -1173,8 +1196,7 @@ std::array x11_to_xt_vnc #endif #ifdef Q_OS_MACOS -std::array darwin_to_xt -{ +std::array darwin_to_xt { 0x1E, 0x1F, 0x20, @@ -1307,143 +1329,142 @@ std::array darwin_to_xt #endif #if defined(__unix__) && !defined(__HAIKU__) -static std::unordered_map evdev_to_xt = - { - {96, 0x11C}, - {97, 0x11D}, - {98, 0x135}, - {99, 0x71}, - {100, 0x138}, - {101, 0x1C}, - {102, 0x147}, - {103, 0x148}, - {104, 0x149}, - {105, 0x14B}, - {106, 0x14D}, - {107, 0x14F}, - {108, 0x150}, - {109, 0x151}, - {110, 0x152}, - {111, 0x153} +static std::unordered_map evdev_to_xt = { + {96, 0x11C}, + { 97, 0x11D}, + { 98, 0x135}, + { 99, 0x71 }, + { 100, 0x138}, + { 101, 0x1C }, + { 102, 0x147}, + { 103, 0x148}, + { 104, 0x149}, + { 105, 0x14B}, + { 106, 0x14D}, + { 107, 0x14F}, + { 108, 0x150}, + { 109, 0x151}, + { 110, 0x152}, + { 111, 0x153} }; #endif #ifdef __HAIKU__ -static std::unordered_map be_to_xt = -{ - {0x01, 0x01}, - {B_F1_KEY, 0x3B}, - {B_F2_KEY, 0x3C}, - {B_F3_KEY, 0x3D}, - {B_F4_KEY, 0x3E}, - {B_F5_KEY, 0x3F}, - {B_F6_KEY, 0x40}, - {B_F7_KEY, 0x41}, - {B_F8_KEY, 0x42}, - {B_F9_KEY, 0x43}, - {B_F10_KEY, 0x44}, - {B_F11_KEY, 0x57}, - {B_F12_KEY, 0x58}, - {0x11, 0x29}, - {0x12, 0x02}, - {0x13, 0x03}, - {0x14, 0x04}, - {0x15, 0x05}, - {0x16, 0x06}, - {0x17, 0x07}, - {0x18, 0x08}, - {0x19, 0x09}, - {0x1A, 0x0A}, - {0x1B, 0x0B}, - {0x1C, 0x0C}, - {0x1D, 0x0D}, - {0x1E, 0x0E}, - {0x1F, 0x152}, - {0x20, 0x147}, - {0x21, 0x149}, - {0x22, 0x45}, - {0x23, 0x135}, - {0x24, 0x37}, - {0x25, 0x4A}, - {0x26, 0x0F}, - {0x27, 0x10}, - {0x28, 0x11}, - {0x29, 0x12}, - {0x2A, 0x13}, - {0x2B, 0x14}, - {0x2C, 0x15}, - {0x2D, 0x16}, - {0x2E, 0x17}, - {0x2F, 0x18}, - {0x30, 0x19}, - {0x31, 0x1A}, - {0x32, 0x1B}, - {0x33, 0x2B}, - {0x34, 0x153}, - {0x35, 0x14F}, - {0x36, 0x151}, - {0x37, 0x47}, - {0x38, 0x48}, - {0x39, 0x49}, - {0x3A, 0x4E}, - {0x3B, 0x3A}, - {0x3C, 0x1E}, - {0x3D, 0x1F}, - {0x3E, 0x20}, - {0x3F, 0x21}, - {0x40, 0x22}, - {0x41, 0x23}, - {0x42, 0x24}, - {0x43, 0x25}, - {0x44, 0x26}, - {0x45, 0x27}, - {0x46, 0x28}, - {0x47, 0x1C}, - {0x48, 0x4B}, - {0x49, 0x4C}, - {0x4A, 0x4D}, - {0x4B, 0x2A}, - {0x4C, 0x2C}, - {0x4D, 0x2D}, - {0x4E, 0x2E}, - {0x4F, 0x2F}, - {0x50, 0x30}, - {0x51, 0x31}, - {0x52, 0x32}, - {0x53, 0x33}, - {0x54, 0x34}, - {0x55, 0x35}, - {0x56, 0x36}, - {0x57, 0x148}, - {0x58, 0x51}, - {0x59, 0x50}, - {0x5A, 0x4F}, - {0x5B, 0x11C}, - {0x5C, 0x1D}, - {0x5D, 0x38}, - {0x5E, 0x39}, - {0x5F, 0x138}, - {0x60, 0x11D}, - {0x61, 0x14B}, - {0x62, 0x150}, - {0x63, 0x14D}, - {0x64, 0x52}, - {0x65, 0x53}, +static std::unordered_map be_to_xt = { + {0x01, 0x01 }, + { B_F1_KEY, 0x3B }, + { B_F2_KEY, 0x3C }, + { B_F3_KEY, 0x3D }, + { B_F4_KEY, 0x3E }, + { B_F5_KEY, 0x3F }, + { B_F6_KEY, 0x40 }, + { B_F7_KEY, 0x41 }, + { B_F8_KEY, 0x42 }, + { B_F9_KEY, 0x43 }, + { B_F10_KEY, 0x44 }, + { B_F11_KEY, 0x57 }, + { B_F12_KEY, 0x58 }, + { 0x11, 0x29 }, + { 0x12, 0x02 }, + { 0x13, 0x03 }, + { 0x14, 0x04 }, + { 0x15, 0x05 }, + { 0x16, 0x06 }, + { 0x17, 0x07 }, + { 0x18, 0x08 }, + { 0x19, 0x09 }, + { 0x1A, 0x0A }, + { 0x1B, 0x0B }, + { 0x1C, 0x0C }, + { 0x1D, 0x0D }, + { 0x1E, 0x0E }, + { 0x1F, 0x152}, + { 0x20, 0x147}, + { 0x21, 0x149}, + { 0x22, 0x45 }, + { 0x23, 0x135}, + { 0x24, 0x37 }, + { 0x25, 0x4A }, + { 0x26, 0x0F }, + { 0x27, 0x10 }, + { 0x28, 0x11 }, + { 0x29, 0x12 }, + { 0x2A, 0x13 }, + { 0x2B, 0x14 }, + { 0x2C, 0x15 }, + { 0x2D, 0x16 }, + { 0x2E, 0x17 }, + { 0x2F, 0x18 }, + { 0x30, 0x19 }, + { 0x31, 0x1A }, + { 0x32, 0x1B }, + { 0x33, 0x2B }, + { 0x34, 0x153}, + { 0x35, 0x14F}, + { 0x36, 0x151}, + { 0x37, 0x47 }, + { 0x38, 0x48 }, + { 0x39, 0x49 }, + { 0x3A, 0x4E }, + { 0x3B, 0x3A }, + { 0x3C, 0x1E }, + { 0x3D, 0x1F }, + { 0x3E, 0x20 }, + { 0x3F, 0x21 }, + { 0x40, 0x22 }, + { 0x41, 0x23 }, + { 0x42, 0x24 }, + { 0x43, 0x25 }, + { 0x44, 0x26 }, + { 0x45, 0x27 }, + { 0x46, 0x28 }, + { 0x47, 0x1C }, + { 0x48, 0x4B }, + { 0x49, 0x4C }, + { 0x4A, 0x4D }, + { 0x4B, 0x2A }, + { 0x4C, 0x2C }, + { 0x4D, 0x2D }, + { 0x4E, 0x2E }, + { 0x4F, 0x2F }, + { 0x50, 0x30 }, + { 0x51, 0x31 }, + { 0x52, 0x32 }, + { 0x53, 0x33 }, + { 0x54, 0x34 }, + { 0x55, 0x35 }, + { 0x56, 0x36 }, + { 0x57, 0x148}, + { 0x58, 0x51 }, + { 0x59, 0x50 }, + { 0x5A, 0x4F }, + { 0x5B, 0x11C}, + { 0x5C, 0x1D }, + { 0x5D, 0x38 }, + { 0x5E, 0x39 }, + { 0x5F, 0x138}, + { 0x60, 0x11D}, + { 0x61, 0x14B}, + { 0x62, 0x150}, + { 0x63, 0x14D}, + { 0x64, 0x52 }, + { 0x65, 0x53 }, - {0x0e, 0x137}, - {0x0f, 0x46}, - {0x66, 0x15B}, - {0x67, 0x15C}, - {0x68, 0x15D}, - {0x69, 0x56} + { 0x0e, 0x137}, + { 0x0f, 0x46 }, + { 0x66, 0x15B}, + { 0x67, 0x15C}, + { 0x68, 0x15D}, + { 0x69, 0x56 } }; #endif #if defined(__unix__) && !defined(__HAIKU__) -static std::array& selected_keycode = x11_to_xt_base; +static std::array &selected_keycode = x11_to_xt_base; #endif -uint16_t x11_keycode_to_keysym(uint32_t keycode) +uint16_t +x11_keycode_to_keysym(uint32_t keycode) { uint16_t finalkeycode = 0; #if defined(Q_OS_WINDOWS) @@ -1453,33 +1474,27 @@ uint16_t x11_keycode_to_keysym(uint32_t keycode) #elif defined(__HAIKU__) finalkeycode = be_to_xt[keycode]; #else - static Display* x11display = nullptr; - if (QApplication::platformName().contains("wayland")) - { + static Display *x11display = nullptr; + if (QApplication::platformName().contains("wayland")) { selected_keycode = x11_to_xt_2; - } - else if (QApplication::platformName().contains("eglfs")) - { + } else if (QApplication::platformName().contains("eglfs")) { keycode -= 8; - if (keycode <= 88) finalkeycode = keycode; - else finalkeycode = evdev_to_xt[keycode]; - } - else if (!x11display) - { + if (keycode <= 88) + finalkeycode = keycode; + else + finalkeycode = evdev_to_xt[keycode]; + } else if (!x11display) { x11display = XOpenDisplay(nullptr); - if (XKeysymToKeycode(x11display, XK_Home) == 110) - { + if (XKeysymToKeycode(x11display, XK_Home) == 110) { selected_keycode = x11_to_xt_2; - } - else if (XKeysymToKeycode(x11display, XK_Home) == 69) - { + } else if (XKeysymToKeycode(x11display, XK_Home) == 69) { selected_keycode = x11_to_xt_vnc; } } - if (!QApplication::platformName().contains("eglfs")) finalkeycode = selected_keycode[keycode]; + if (!QApplication::platformName().contains("eglfs")) + finalkeycode = selected_keycode[keycode]; #endif - if (rctrl_is_lalt && finalkeycode == 0x11D) - { + if (rctrl_is_lalt && finalkeycode == 0x11D) { finalkeycode = 0x38; } return finalkeycode; @@ -1490,18 +1505,20 @@ uint16_t x11_keycode_to_keysym(uint32_t keycode) // that's followed up with "(really?)". It's the only way to distinguish // left and right modifiers with Qt 6 on macOS, so let's just roll with it. static std::unordered_map mac_modifiers_to_xt = { - {NX_DEVICELCTLKEYMASK, 0x1D}, - {NX_DEVICELSHIFTKEYMASK, 0x2A}, - {NX_DEVICERSHIFTKEYMASK, 0x36}, - {NX_DEVICELCMDKEYMASK, 0x15B}, - {NX_DEVICERCMDKEYMASK, 0x15C}, - {NX_DEVICELALTKEYMASK, 0x38}, - {NX_DEVICERALTKEYMASK, 0x138}, - {NX_DEVICE_ALPHASHIFT_STATELESS_MASK, 0x3A}, - {NX_DEVICERCTLKEYMASK, 0x11D}, + {NX_DEVICELCTLKEYMASK, 0x1D }, + { NX_DEVICELSHIFTKEYMASK, 0x2A }, + { NX_DEVICERSHIFTKEYMASK, 0x36 }, + { NX_DEVICELCMDKEYMASK, 0x15B}, + { NX_DEVICERCMDKEYMASK, 0x15C}, + { NX_DEVICELALTKEYMASK, 0x38 }, + { NX_DEVICERALTKEYMASK, 0x138}, + { NX_DEVICE_ALPHASHIFT_STATELESS_MASK, 0x3A }, + { NX_DEVICERCTLKEYMASK, 0x11D}, }; -void MainWindow::processMacKeyboardInput(bool down, const QKeyEvent* event) { +void +MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event) +{ // Per QTBUG-69608 (https://bugreports.qt.io/browse/QTBUG-69608), // QKeyEvents QKeyEvents for presses/releases of modifiers on macOS give // nativeVirtualKey() == 0 (at least in Qt 6). Handle this by manually @@ -1518,7 +1535,7 @@ void MainWindow::processMacKeyboardInput(bool down, const QKeyEvent* event) { // We only process one modifier at a time since events from Qt seem to // always be non-coalesced (NX_NONCOALESCEDMASK is always set). uint32_t changed_modifiers = last_modifiers ^ event->nativeModifiers(); - for (auto const& pair : mac_modifiers_to_xt) { + for (auto const &pair : mac_modifiers_to_xt) { if (changed_modifiers & pair.first) { last_modifiers ^= pair.first; keyboard_input(down, pair.second); @@ -1547,24 +1564,28 @@ void MainWindow::processMacKeyboardInput(bool down, const QKeyEvent* event) { } #endif -void MainWindow::on_actionFullscreen_triggered() { +void +MainWindow::on_actionFullscreen_triggered() +{ if (video_fullscreen > 0) { showNormal(); - if (vid_api == 5) QTimer::singleShot(0, this, [this] () { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); + if (vid_api == 5) + QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); ui->menubar->show(); - if (!hide_status_bar) ui->statusbar->show(); - if (!hide_tool_bar) ui->toolBar->show(); + if (!hide_status_bar) + ui->statusbar->show(); + if (!hide_tool_bar) + ui->toolBar->show(); video_fullscreen = 0; if (vid_resize != 1) { emit resizeContents(vid_resize == 2 ? fixed_size_x : monitors[0].mon_scrnsz_x, vid_resize == 2 ? fixed_size_y : monitors[0].mon_scrnsz_y); } } else { - if (video_fullscreen_first) - { + if (video_fullscreen_first) { bool wasCaptured = mouse_capture == 1; QMessageBox questionbox(QMessageBox::Icon::Information, tr("Entering fullscreen mode"), tr("Press Ctrl+Alt+PgDn to return to windowed mode."), QMessageBox::Ok, this); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!video_fullscreen_first); @@ -1585,17 +1606,20 @@ void MainWindow::on_actionFullscreen_triggered() { ui->toolBar->hide(); ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); showFullScreen(); - if (vid_api == 5) QTimer::singleShot(0, this, [this] () { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); + if (vid_api == 5) + QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); } ui->stackedWidget->onResize(width(), height()); } -void MainWindow::getTitle_(wchar_t *title) +void +MainWindow::getTitle_(wchar_t *title) { this->windowTitle().toWCharArray(title); } -void MainWindow::getTitle(wchar_t *title) +void +MainWindow::getTitle(wchar_t *title) { if (QThread::currentThread() == this->thread()) { getTitle_(title); @@ -1604,11 +1628,12 @@ void MainWindow::getTitle(wchar_t *title) } } -bool MainWindow::eventFilter(QObject* receiver, QEvent* event) +bool +MainWindow::eventFilter(QObject *receiver, QEvent *event) { if (!dopause && (mouse_capture || !kbd_req_capture)) { if (event->type() == QEvent::Shortcut) { - auto shortcutEvent = (QShortcutEvent*)event; + auto shortcutEvent = (QShortcutEvent *) event; if (shortcutEvent->key() == ui->actionExit->shortcut()) { event->accept(); return true; @@ -1640,13 +1665,17 @@ bool MainWindow::eventFilter(QObject* receiver, QEvent* event) return QMainWindow::eventFilter(receiver, event); } -void MainWindow::refreshMediaMenu() { +void +MainWindow::refreshMediaMenu() +{ mm->refresh(ui->menuMedia); status->refresh(ui->statusbar); ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); } -void MainWindow::showMessage(int flags, const QString& header, const QString& message) { +void +MainWindow::showMessage(int flags, const QString &header, const QString &message) +{ if (QThread::currentThread() == this->thread()) { showMessage_(flags, header, message); } else { @@ -1654,23 +1683,25 @@ void MainWindow::showMessage(int flags, const QString& header, const QString& me } } -void MainWindow::showMessage_(int flags, const QString &header, const QString &message) { +void +MainWindow::showMessage_(int flags, const QString &header, const QString &message) +{ QMessageBox box(QMessageBox::Warning, header, message, QMessageBox::NoButton, this); if (flags & (MBX_FATAL)) { box.setIcon(QMessageBox::Critical); - } - else if (!(flags & (MBX_ERROR | MBX_WARNING))) { + } else if (!(flags & (MBX_ERROR | MBX_WARNING))) { box.setIcon(QMessageBox::Warning); } box.setTextFormat(Qt::TextFormat::RichText); box.exec(); - if (cpu_thread_run == 0) QApplication::exit(-1); + if (cpu_thread_run == 0) + QApplication::exit(-1); } -void MainWindow::keyPressEvent(QKeyEvent* event) +void +MainWindow::keyPressEvent(QKeyEvent *event) { - if (send_keyboard_input && !(kbd_req_capture && !mouse_capture)) - { + if (send_keyboard_input && !(kbd_req_capture && !mouse_capture)) { // Windows keys in Qt have one-to-one mapping. if (event->key() == Qt::Key_Pause && !keyboard_recv(0x38) && !keyboard_recv(0x138)) { if ((keyboard_recv(0x1D) || keyboard_recv(0x11D))) { @@ -1685,9 +1716,9 @@ void MainWindow::keyPressEvent(QKeyEvent* event) } } else #ifdef Q_OS_MACOS - processMacKeyboardInput(true, event); + processMacKeyboardInput(true, event); #else - keyboard_input(1, x11_keycode_to_keysym(event->nativeScanCode())); + keyboard_input(1, x11_keycode_to_keysym(event->nativeScanCode())); #endif } @@ -1700,23 +1731,29 @@ void MainWindow::keyPressEvent(QKeyEvent* event) } if ((video_fullscreen > 0) && (keyboard_recv(0x1D) || keyboard_recv(0x11D))) { - if (keyboard_recv(0x57)) ui->actionTake_screenshot->trigger(); - else if (keyboard_recv(0x58)) pc_send_cad(); + if (keyboard_recv(0x57)) + ui->actionTake_screenshot->trigger(); + else if (keyboard_recv(0x58)) + pc_send_cad(); } event->accept(); } -void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) +void +MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) { if (monitor_index >= 1) { - if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible()) renderers[monitor_index]->blit(x, y, w, h); - else video_blit_complete_monitor(monitor_index); - } - else ui->stackedWidget->blit(x, y, w, h); + if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible()) + renderers[monitor_index]->blit(x, y, w, h); + else + video_blit_complete_monitor(monitor_index); + } else + ui->stackedWidget->blit(x, y, w, h); } -void MainWindow::keyReleaseEvent(QKeyEvent* event) +void +MainWindow::keyReleaseEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Pause) { if (keyboard_recv(0x38) && keyboard_recv(0x138)) { @@ -1733,22 +1770,27 @@ void MainWindow::keyReleaseEvent(QKeyEvent* event) #endif } -QSize MainWindow::getRenderWidgetSize() +QSize +MainWindow::getRenderWidgetSize() { return ui->stackedWidget->size(); } -void MainWindow::focusInEvent(QFocusEvent* event) +void +MainWindow::focusInEvent(QFocusEvent *event) { this->grabKeyboard(); } -void MainWindow::focusOutEvent(QFocusEvent* event) +void +MainWindow::focusOutEvent(QFocusEvent *event) { this->releaseKeyboard(); } -void MainWindow::on_actionResizable_window_triggered(bool checked) { +void +MainWindow::on_actionResizable_window_triggered(bool checked) +{ if (checked) { vid_resize = 1; setWindowFlag(Qt::WindowMaximizeButtonHint); @@ -1772,20 +1814,20 @@ void MainWindow::on_actionResizable_window_triggered(bool checked) { } } show(); - ui->menuWindow_scale_factor->setEnabled(! checked); + ui->menuWindow_scale_factor->setEnabled(!checked); emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y); - ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api); + ui->stackedWidget->switchRenderer((RendererStack::Renderer) vid_api); for (int i = 1; i < MONITORS_NUM; i++) { if (monitors[i].target_buffer && show_second_monitors) { renderers[i]->show(); - renderers[i]->switchRenderer((RendererStack::Renderer)vid_api); + renderers[i]->switchRenderer((RendererStack::Renderer) vid_api); QApplication::processEvents(); } } } static void -video_toggle_option(QAction* action, int *val) +video_toggle_option(QAction *action, int *val) { startblit(); *val ^= 1; @@ -1795,15 +1837,20 @@ video_toggle_option(QAction* action, int *val) config_save(); device_force_redraw(); for (int i = 0; i < MONITORS_NUM; i++) { - if (monitors[i].target_buffer) video_force_resize_set_monitor(1, i); + if (monitors[i].target_buffer) + video_force_resize_set_monitor(1, i); } } -void MainWindow::on_actionInverted_VGA_monitor_triggered() { +void +MainWindow::on_actionInverted_VGA_monitor_triggered() +{ video_toggle_option(ui->actionInverted_VGA_monitor, &invert_display); } -static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { +static void +update_scaled_checkboxes(Ui::MainWindow *ui, QAction *selected) +{ ui->action0_5x->setChecked(ui->action0_5x == selected); ui->action1x->setChecked(ui->action1x == selected); ui->action1_5x->setChecked(ui->action1_5x == selected); @@ -1818,72 +1865,99 @@ static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { reset_screen_size(); device_force_redraw(); for (int i = 0; i < MONITORS_NUM; i++) { - if (monitors[i].target_buffer) video_force_resize_set_monitor(1, i); + if (monitors[i].target_buffer) + video_force_resize_set_monitor(1, i); } config_save(); } -void MainWindow::on_action0_5x_triggered() { +void +MainWindow::on_action0_5x_triggered() +{ scale = 0; update_scaled_checkboxes(ui, ui->action0_5x); } -void MainWindow::on_action1x_triggered() { +void +MainWindow::on_action1x_triggered() +{ scale = 1; update_scaled_checkboxes(ui, ui->action1x); } -void MainWindow::on_action1_5x_triggered() { +void +MainWindow::on_action1_5x_triggered() +{ scale = 2; update_scaled_checkboxes(ui, ui->action1_5x); } -void MainWindow::on_action2x_triggered() { +void +MainWindow::on_action2x_triggered() +{ scale = 3; update_scaled_checkboxes(ui, ui->action2x); } -void MainWindow::on_action3x_triggered() { +void +MainWindow::on_action3x_triggered() +{ scale = 4; update_scaled_checkboxes(ui, ui->action3x); } -void MainWindow::on_action4x_triggered() { +void +MainWindow::on_action4x_triggered() +{ scale = 5; update_scaled_checkboxes(ui, ui->action4x); } -void MainWindow::on_action5x_triggered() { +void +MainWindow::on_action5x_triggered() +{ scale = 6; update_scaled_checkboxes(ui, ui->action5x); } -void MainWindow::on_action6x_triggered() { +void +MainWindow::on_action6x_triggered() +{ scale = 7; update_scaled_checkboxes(ui, ui->action6x); } -void MainWindow::on_action7x_triggered() { +void +MainWindow::on_action7x_triggered() +{ scale = 8; update_scaled_checkboxes(ui, ui->action7x); } -void MainWindow::on_action8x_triggered() { +void +MainWindow::on_action8x_triggered() +{ scale = 9; update_scaled_checkboxes(ui, ui->action8x); } -void MainWindow::on_actionNearest_triggered() { +void +MainWindow::on_actionNearest_triggered() +{ video_filter_method = 0; ui->actionLinear->setChecked(false); } -void MainWindow::on_actionLinear_triggered() { +void +MainWindow::on_actionLinear_triggered() +{ video_filter_method = 1; ui->actionNearest->setChecked(false); } -static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* selected) { +static void +update_fullscreen_scale_checkboxes(Ui::MainWindow *ui, QAction *selected) +{ ui->actionFullScreen_stretch->setChecked(ui->actionFullScreen_stretch == selected); ui->actionFullScreen_43->setChecked(ui->actionFullScreen_43 == selected); ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected); @@ -1895,34 +1969,45 @@ static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* sele } for (int i = 1; i < MONITORS_NUM; i++) { - if (main_window->renderers[i]) main_window->renderers[i]->onResize(main_window->renderers[i]->width(), main_window->renderers[i]->height()); + if (main_window->renderers[i]) + main_window->renderers[i]->onResize(main_window->renderers[i]->width(), main_window->renderers[i]->height()); } device_force_redraw(); config_save(); } -void MainWindow::on_actionFullScreen_stretch_triggered() { +void +MainWindow::on_actionFullScreen_stretch_triggered() +{ video_fullscreen_scale = FULLSCR_SCALE_FULL; update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_stretch); } -void MainWindow::on_actionFullScreen_43_triggered() { +void +MainWindow::on_actionFullScreen_43_triggered() +{ video_fullscreen_scale = FULLSCR_SCALE_43; update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_43); } -void MainWindow::on_actionFullScreen_keepRatio_triggered() { +void +MainWindow::on_actionFullScreen_keepRatio_triggered() +{ video_fullscreen_scale = FULLSCR_SCALE_KEEPRATIO; update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_keepRatio); } -void MainWindow::on_actionFullScreen_int_triggered() { +void +MainWindow::on_actionFullScreen_int_triggered() +{ video_fullscreen_scale = FULLSCR_SCALE_INT; update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_int); } -static void update_greyscale_checkboxes(Ui::MainWindow* ui, QAction* selected, int value) { +static void +update_greyscale_checkboxes(Ui::MainWindow *ui, QAction *selected, int value) +{ ui->actionRGB_Color->setChecked(ui->actionRGB_Color == selected); ui->actionRGB_Grayscale->setChecked(ui->actionRGB_Grayscale == selected); ui->actionAmber_monitor->setChecked(ui->actionAmber_monitor == selected); @@ -1931,33 +2016,45 @@ static void update_greyscale_checkboxes(Ui::MainWindow* ui, QAction* selected, i startblit(); video_grayscale = value; - video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; endblit(); device_force_redraw(); config_save(); } -void MainWindow::on_actionRGB_Color_triggered() { +void +MainWindow::on_actionRGB_Color_triggered() +{ update_greyscale_checkboxes(ui, ui->actionRGB_Color, 0); } -void MainWindow::on_actionRGB_Grayscale_triggered() { +void +MainWindow::on_actionRGB_Grayscale_triggered() +{ update_greyscale_checkboxes(ui, ui->actionRGB_Grayscale, 1); } -void MainWindow::on_actionAmber_monitor_triggered() { +void +MainWindow::on_actionAmber_monitor_triggered() +{ update_greyscale_checkboxes(ui, ui->actionAmber_monitor, 2); } -void MainWindow::on_actionGreen_monitor_triggered() { +void +MainWindow::on_actionGreen_monitor_triggered() +{ update_greyscale_checkboxes(ui, ui->actionGreen_monitor, 3); } -void MainWindow::on_actionWhite_monitor_triggered() { +void +MainWindow::on_actionWhite_monitor_triggered() +{ update_greyscale_checkboxes(ui, ui->actionWhite_monitor, 4); } -static void update_greyscale_type_checkboxes(Ui::MainWindow* ui, QAction* selected, int value) { +static void +update_greyscale_type_checkboxes(Ui::MainWindow *ui, QAction *selected, int value) +{ ui->actionBT601_NTSC_PAL->setChecked(ui->actionBT601_NTSC_PAL == selected); ui->actionBT709_HDTV->setChecked(ui->actionBT709_HDTV == selected); ui->actionAverage->setChecked(ui->actionAverage == selected); @@ -1967,24 +2064,32 @@ static void update_greyscale_type_checkboxes(Ui::MainWindow* ui, QAction* select config_save(); } -void MainWindow::on_actionBT601_NTSC_PAL_triggered() { +void +MainWindow::on_actionBT601_NTSC_PAL_triggered() +{ update_greyscale_type_checkboxes(ui, ui->actionBT601_NTSC_PAL, 0); } -void MainWindow::on_actionBT709_HDTV_triggered() { +void +MainWindow::on_actionBT709_HDTV_triggered() +{ update_greyscale_type_checkboxes(ui, ui->actionBT709_HDTV, 1); } -void MainWindow::on_actionAverage_triggered() { +void +MainWindow::on_actionAverage_triggered() +{ update_greyscale_type_checkboxes(ui, ui->actionAverage, 2); } -void MainWindow::on_actionAbout_Qt_triggered() +void +MainWindow::on_actionAbout_Qt_triggered() { QApplication::aboutQt(); } -void MainWindow::on_actionAbout_86Box_triggered() +void +MainWindow::on_actionAbout_86Box_triggered() { QMessageBox msgBox; msgBox.setTextFormat(Qt::RichText); @@ -1997,8 +2102,7 @@ void MainWindow::on_actionAbout_86Box_triggered() msgBox.setWindowTitle("About 86Box"); msgBox.addButton("OK", QMessageBox::ButtonRole::AcceptRole); auto webSiteButton = msgBox.addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); - webSiteButton->connect(webSiteButton, &QPushButton::released, []() - { + webSiteButton->connect(webSiteButton, &QPushButton::released, []() { QDesktopServices::openUrl(QUrl("https://" EMU_SITE)); }); #ifdef RELEASE_BUILD @@ -2014,27 +2118,35 @@ void MainWindow::on_actionAbout_86Box_triggered() msgBox.exec(); } -void MainWindow::on_actionDocumentation_triggered() +void +MainWindow::on_actionDocumentation_triggered() { - QDesktopServices::openUrl(QUrl(EMU_DOCS_URL)); + QDesktopServices::openUrl(QUrl(EMU_DOCS_URL)); } -void MainWindow::on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered() { +void +MainWindow::on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered() +{ update_overscan = 1; video_toggle_option(ui->actionCGA_PCjr_Tandy_EGA_S_VGA_overscan, &enable_overscan); } -void MainWindow::on_actionChange_contrast_for_monochrome_display_triggered() { +void +MainWindow::on_actionChange_contrast_for_monochrome_display_triggered() +{ vid_cga_contrast ^= 1; cgapal_rebuild(); config_save(); } -void MainWindow::on_actionForce_4_3_display_ratio_triggered() { +void +MainWindow::on_actionForce_4_3_display_ratio_triggered() +{ video_toggle_option(ui->actionForce_4_3_display_ratio, &force_43); } -void MainWindow::on_actionRemember_size_and_position_triggered() +void +MainWindow::on_actionRemember_size_and_position_triggered() { window_remember ^= 1; window_w = ui->stackedWidget->width(); @@ -2054,24 +2166,28 @@ void MainWindow::on_actionRemember_size_and_position_triggered() ui->actionRemember_size_and_position->setChecked(window_remember); } -void MainWindow::on_actionSpecify_dimensions_triggered() +void +MainWindow::on_actionSpecify_dimensions_triggered() { SpecifyDimensions dialog(this); dialog.setWindowModality(Qt::WindowModal); dialog.exec(); } -void MainWindow::on_actionHiDPI_scaling_triggered() +void +MainWindow::on_actionHiDPI_scaling_triggered() { dpi_scale ^= 1; ui->actionHiDPI_scaling->setChecked(dpi_scale); emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y); for (int i = 1; i < MONITORS_NUM; i++) { - if (renderers[i]) emit resizeContentsMonitor(monitors[i].mon_scrnsz_x, monitors[i].mon_scrnsz_y, i); + if (renderers[i]) + emit resizeContentsMonitor(monitors[i].mon_scrnsz_x, monitors[i].mon_scrnsz_y, i); } } -void MainWindow::on_actionHide_status_bar_triggered() +void +MainWindow::on_actionHide_status_bar_triggered() { auto w = ui->stackedWidget->width(); auto h = ui->stackedWidget->height(); @@ -2079,20 +2195,19 @@ void MainWindow::on_actionHide_status_bar_triggered() ui->actionHide_status_bar->setChecked(hide_status_bar); statusBar()->setVisible(!hide_status_bar); if (vid_resize >= 2) { - setFixedSize(fixed_size_x, fixed_size_y - + menuBar()->height() - + (hide_status_bar ? 0 : statusBar()->height()) - + (hide_tool_bar ? 0 : ui->toolBar->height())); + setFixedSize(fixed_size_x, fixed_size_y + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); } else { int vid_resize_orig = vid_resize; - vid_resize = 0; + vid_resize = 0; emit resizeContents(w, h); vid_resize = vid_resize_orig; - if (vid_resize == 1) setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + if (vid_resize == 1) + setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } } -void MainWindow::on_actionHide_tool_bar_triggered() +void +MainWindow::on_actionHide_tool_bar_triggered() { auto w = ui->stackedWidget->width(); auto h = ui->stackedWidget->height(); @@ -2100,26 +2215,26 @@ void MainWindow::on_actionHide_tool_bar_triggered() ui->actionHide_tool_bar->setChecked(hide_tool_bar); ui->toolBar->setVisible(!hide_tool_bar); if (vid_resize >= 2) { - setFixedSize(fixed_size_x, fixed_size_y - + menuBar()->height() - + (hide_status_bar ? 0 : statusBar()->height()) - + (hide_tool_bar ? 0 : ui->toolBar->height())); + setFixedSize(fixed_size_x, fixed_size_y + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); } else { int vid_resize_orig = vid_resize; - vid_resize = 0; + vid_resize = 0; emit resizeContents(w, h); vid_resize = vid_resize_orig; - if (vid_resize == 1) setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + if (vid_resize == 1) + setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } } -void MainWindow::on_actionUpdate_status_bar_icons_triggered() +void +MainWindow::on_actionUpdate_status_bar_icons_triggered() { update_icons ^= 1; ui->actionUpdate_status_bar_icons->setChecked(update_icons); } -void MainWindow::on_actionTake_screenshot_triggered() +void +MainWindow::on_actionTake_screenshot_triggered() { startblit(); for (int i = 0; i < MONITORS_NUM; i++) @@ -2128,62 +2243,70 @@ void MainWindow::on_actionTake_screenshot_triggered() device_force_redraw(); } -void MainWindow::on_actionSound_gain_triggered() +void +MainWindow::on_actionSound_gain_triggered() { SoundGain gain(this); gain.exec(); } -void MainWindow::setSendKeyboardInput(bool enabled) +void +MainWindow::setSendKeyboardInput(bool enabled) { send_keyboard_input = enabled; } -void MainWindow::updateUiPauseState() { +void +MainWindow::updateUiPauseState() +{ auto pause_icon = dopause ? QIcon(":/menuicons/win/icons/run.ico") : QIcon(":/menuicons/win/icons/pause.ico"); auto tooltip_text = dopause ? QString(tr("Resume execution")) : QString(tr("Pause execution")); ui->actionPause->setIcon(pause_icon); ui->actionPause->setToolTip(tooltip_text); } -void MainWindow::on_actionPreferences_triggered() +void +MainWindow::on_actionPreferences_triggered() { ProgSettings progsettings(this); progsettings.exec(); } - -void MainWindow::on_actionEnable_Discord_integration_triggered(bool checked) +void +MainWindow::on_actionEnable_Discord_integration_triggered(bool checked) { enable_discord = checked; - if(enable_discord) { + if (enable_discord) { discord_init(); discord_update_activity(dopause); } else discord_close(); } -void MainWindow::showSettings() +void +MainWindow::showSettings() { - if (findChild() == nullptr) + if (findChild() == nullptr) ui->actionSettings->trigger(); } -void MainWindow::hardReset() +void +MainWindow::hardReset() { ui->actionHard_Reset->trigger(); } -void MainWindow::togglePause() +void +MainWindow::togglePause() { ui->actionPause->trigger(); } -void MainWindow::changeEvent(QEvent* event) +void +MainWindow::changeEvent(QEvent *event) { #ifdef Q_OS_WINDOWS - if (event->type() == QEvent::LanguageChange) - { + if (event->type() == QEvent::LanguageChange) { auto font_name = tr("FONT_NAME"); auto font_size = tr("FONT_SIZE"); QApplication::setFont(QFont(font_name, font_size.toInt())); @@ -2196,20 +2319,23 @@ void MainWindow::changeEvent(QEvent* event) } } -void MainWindow::on_actionRenderer_options_triggered() +void +MainWindow::on_actionRenderer_options_triggered() { auto dlg = ui->stackedWidget->getOptions(this); if (dlg) { if (dlg->exec() == QDialog::Accepted) { for (int i = 1; i < MONITORS_NUM; i++) { - if (renderers[i] && renderers[i]->hasOptions()) renderers[i]->reloadOptions(); + if (renderers[i] && renderers[i]->hasOptions()) + renderers[i]->reloadOptions(); } } } } -void MainWindow::on_actionMCA_devices_triggered() +void +MainWindow::on_actionMCA_devices_triggered() { auto dlg = new MCADeviceList(this); @@ -2217,30 +2343,32 @@ void MainWindow::on_actionMCA_devices_triggered() dlg->exec(); } - -void MainWindow::on_actionShow_non_primary_monitors_triggered() +void +MainWindow::on_actionShow_non_primary_monitors_triggered() { - show_second_monitors = (int)ui->actionShow_non_primary_monitors->isChecked(); + show_second_monitors = (int) ui->actionShow_non_primary_monitors->isChecked(); blitDummied = true; if (show_second_monitors) { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { - auto& secondaryRenderer = renderers[monitor_index]; - if (!renderers[monitor_index]) continue; + auto &secondaryRenderer = renderers[monitor_index]; + if (!renderers[monitor_index]) + continue; secondaryRenderer->show(); if (window_remember) { secondaryRenderer->setGeometry(monitor_settings[monitor_index].mon_window_x < 120 ? 120 : monitor_settings[monitor_index].mon_window_x, - monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y, - monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, - monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); + monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y, + monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, + monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); } - secondaryRenderer->switchRenderer((RendererStack::Renderer)vid_api); + secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); } } else { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { - auto& secondaryRenderer = renderers[monitor_index]; - if (!renderers[monitor_index]) continue; + auto &secondaryRenderer = renderers[monitor_index]; + if (!renderers[monitor_index]) + continue; secondaryRenderer->hide(); if (window_remember && renderers[monitor_index]) { monitor_settings[monitor_index].mon_window_w = renderers[monitor_index]->geometry().width(); @@ -2254,15 +2382,15 @@ void MainWindow::on_actionShow_non_primary_monitors_triggered() blitDummied = false; } - -void MainWindow::on_actionOpen_screenshots_folder_triggered() +void +MainWindow::on_actionOpen_screenshots_folder_triggered() { QDir(QString(usr_path) + QString("/screenshots/")).mkpath("."); QDesktopServices::openUrl(QUrl(QString("file:///") + usr_path + QString("/screenshots/"))); } - -void MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked) +void +MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked) { video_fullscreen_scale_maximized = checked; @@ -2270,10 +2398,10 @@ void MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered ui->stackedWidget->onResize(widget->width(), widget->height()); for (int i = 1; i < MONITORS_NUM; i++) { - if (renderers[i]) renderers[i]->onResize(renderers[i]->width(), renderers[i]->height()); + if (renderers[i]) + renderers[i]->onResize(renderers[i]->width(), renderers[i]->height()); } device_force_redraw(); config_save(); } - diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 692b9c3f0..6ad4c9beb 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -20,27 +20,26 @@ class MainWindow; class MachineStatus; -class MainWindow : public QMainWindow -{ +class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); - void showMessage(int flags, const QString& header, const QString& message); - void getTitle(wchar_t* title); - void blitToWidget(int x, int y, int w, int h, int monitor_index); + void showMessage(int flags, const QString &header, const QString &message); + void getTitle(wchar_t *title); + void blitToWidget(int x, int y, int w, int h, int monitor_index); QSize getRenderWidgetSize(); - void setSendKeyboardInput(bool enabled); + void setSendKeyboardInput(bool enabled); std::array, 8> renderers; signals: - void paint(const QImage& image); + void paint(const QImage &image); void resizeContents(int w, int h); void resizeContentsMonitor(int w, int h, int monitor_index); void pollMouse(); - void statusBarMessage(const QString& msg); + void statusBarMessage(const QString &msg); void updateStatusBarPanes(); void updateStatusBarActivity(int tag, bool active); void updateStatusBarEmpty(int tag, bool empty); @@ -52,12 +51,12 @@ signals: void initRendererMonitorForNonQtThread(int monitor_index); void destroyRendererMonitorForNonQtThread(int monitor_index); - void setTitle(const QString& title); + void setTitle(const QString &title); void setFullscreen(bool state); void setMouseCapture(bool state); - void showMessageForNonQtThread(int flags, const QString& header, const QString& message); - void getTitleForNonQtThread(wchar_t* title); + void showMessageForNonQtThread(int flags, const QString &header, const QString &message); + void getTitleForNonQtThread(wchar_t *title); public slots: void showSettings(); void hardReset(); @@ -120,43 +119,43 @@ private slots: void on_actionRenderer_options_triggered(); void refreshMediaMenu(); - void showMessage_(int flags, const QString& header, const QString& message); - void getTitle_(wchar_t* title); + void showMessage_(int flags, const QString &header, const QString &message); + void getTitle_(wchar_t *title); void on_actionMCA_devices_triggered(); protected: - void keyPressEvent(QKeyEvent* event) override; - void keyReleaseEvent(QKeyEvent* event) override; - void focusInEvent(QFocusEvent* event) override; - void focusOutEvent(QFocusEvent* event) override; - bool eventFilter(QObject* receiver, QEvent* event) override; - void showEvent(QShowEvent* event) override; - void closeEvent(QCloseEvent* event) override; - void changeEvent(QEvent* event) override; + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + bool eventFilter(QObject *receiver, QEvent *event) override; + void showEvent(QShowEvent *event) override; + void closeEvent(QCloseEvent *event) override; + void changeEvent(QEvent *event) override; private slots: void on_actionShow_non_primary_monitors_triggered(); - void on_actionOpen_screenshots_folder_triggered(); + void on_actionOpen_screenshots_folder_triggered(); void on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked); private: - Ui::MainWindow *ui; + Ui::MainWindow *ui; std::unique_ptr status; - std::shared_ptr mm; + std::shared_ptr mm; #ifdef Q_OS_MACOS uint32_t last_modifiers = 0; - void processMacKeyboardInput(bool down, const QKeyEvent* event); + void processMacKeyboardInput(bool down, const QKeyEvent *event); #endif /* If main window should send keyboard input */ bool send_keyboard_input = true; - bool shownonce = false; - bool resizableonce = false; - bool vnc_enabled = false; + bool shownonce = false; + bool resizableonce = false; + bool vnc_enabled = false; friend class SpecifyDimensions; friend class ProgSettings; diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index fcc337cb3..6a86b632e 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -218,6 +218,9 @@ toolBar + + true + false diff --git a/src/qt/qt_mcadevicelist.cpp b/src/qt/qt_mcadevicelist.cpp index f1a39e358..95ae17f45 100644 --- a/src/qt/qt_mcadevicelist.cpp +++ b/src/qt/qt_mcadevicelist.cpp @@ -1,33 +1,27 @@ #include "qt_mcadevicelist.hpp" #include "ui_qt_mcadevicelist.h" -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/video.h> #include <86box/mca.h> #include <86box/plat.h> } -MCADeviceList::MCADeviceList(QWidget *parent) : - QDialog(parent), - ui(new Ui::MCADeviceList) +MCADeviceList::MCADeviceList(QWidget *parent) + : QDialog(parent) + , ui(new Ui::MCADeviceList) { ui->setupUi(this); startblit(); - if (mca_get_nr_cards() == 0) - { + if (mca_get_nr_cards() == 0) { ui->listWidget->addItem(QObject::tr("No MCA devices.")); ui->listWidget->setDisabled(true); - } - else - { - for (int i = 0; i < mca_get_nr_cards(); i++) - { + } else { + for (int i = 0; i < mca_get_nr_cards(); i++) { uint32_t deviceId = (mca_read_index(0x00, i) | (mca_read_index(0x01, i) << 8)); - if (deviceId != 0xFFFF) - { + if (deviceId != 0xFFFF) { QString hexRepresentation = QString::number(deviceId, 16).toUpper(); ui->listWidget->addItem(QString("Slot %1: 0x%2 (@%3.ADF)").arg(i + 1).arg(hexRepresentation, hexRepresentation)); } diff --git a/src/qt/qt_mcadevicelist.hpp b/src/qt/qt_mcadevicelist.hpp index e45992519..41b23c943 100644 --- a/src/qt/qt_mcadevicelist.hpp +++ b/src/qt/qt_mcadevicelist.hpp @@ -7,8 +7,7 @@ namespace Ui { class MCADeviceList; } -class MCADeviceList : public QDialog -{ +class MCADeviceList : public QDialog { Q_OBJECT public: diff --git a/src/qt/qt_mediahistorymanager.cpp b/src/qt/qt_mediahistorymanager.cpp index 19025d210..5564afd46 100644 --- a/src/qt/qt_mediahistorymanager.cpp +++ b/src/qt/qt_mediahistorymanager.cpp @@ -1,20 +1,19 @@ /* -* 86Box A hypervisor and IBM PC system emulator that specializes in -* running old operating systems and software designed for IBM -* PC systems and compatibles from 1981 through fairly recent -* system designs based on the PCI bus. -* -* This file is part of the 86Box distribution. -* -* Media history management module -* -* -* -* Authors: cold-brewed -* -* Copyright 2022 The 86Box development team -*/ - + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Media history management module + * + * + * + * Authors: cold-brewed + * + * Copyright 2022 The 86Box development team + */ #include #include @@ -23,8 +22,7 @@ #include #include "qt_mediahistorymanager.hpp" -extern "C" -{ +extern "C" { #include <86box/timer.h> #include <86box/cdrom.h> #include <86box/fdd.h> @@ -32,23 +30,23 @@ extern "C" namespace ui { -MediaHistoryManager::MediaHistoryManager() { +MediaHistoryManager::MediaHistoryManager() +{ initializeImageHistory(); deserializeAllImageHistory(); initialDeduplication(); - } MediaHistoryManager::~MediaHistoryManager() -= default; + = default; master_list_t & MediaHistoryManager::blankImageHistory(master_list_t &initialized_master_list) const { - for ( const auto device_type : ui::AllSupportedMediaHistoryTypes ) { + for (const auto device_type : ui::AllSupportedMediaHistoryTypes) { device_media_history_t device_media_history; // Loop for all possible media devices - for (int device_index = 0 ; device_index < maxDevicesSupported(device_type); device_index++) { + for (int device_index = 0; device_index < maxDevicesSupported(device_type); device_index++) { device_index_list_t indexing_list; device_media_history[device_index] = indexing_list; // Loop for each history slot @@ -61,12 +59,11 @@ MediaHistoryManager::blankImageHistory(master_list_t &initialized_master_list) c return initialized_master_list; } - -const device_index_list_t& +const device_index_list_t & MediaHistoryManager::getHistoryListForDeviceIndex(int index, ui::MediaType type) { if (master_list.contains(type)) { - if ((index >= 0 ) && (index < master_list[type].size())) { + if ((index >= 0) && (index < master_list[type].size())) { return master_list[type][index]; } else { qWarning("Media device index %i for device type %s was requested but index %i is out of range (valid range: >= 0 && < %i)", @@ -77,7 +74,8 @@ MediaHistoryManager::getHistoryListForDeviceIndex(int index, ui::MediaType type) return empty_device_index_list; } -void MediaHistoryManager::setHistoryListForDeviceIndex(int index, ui::MediaType type, device_index_list_t history_list) +void +MediaHistoryManager::setHistoryListForDeviceIndex(int index, ui::MediaType type, device_index_list_t history_list) { master_list[type][index] = std::move(history_list); } @@ -85,7 +83,7 @@ void MediaHistoryManager::setHistoryListForDeviceIndex(int index, ui::MediaType QString MediaHistoryManager::getImageForSlot(int index, int slot, ui::MediaType type) { - QString image_name; + QString image_name; device_index_list_t device_history = getHistoryListForDeviceIndex(index, type); if ((slot >= 0) && (slot < device_history.size())) { image_name = device_history[slot]; @@ -99,44 +97,47 @@ MediaHistoryManager::getImageForSlot(int index, int slot, ui::MediaType type) // These are hardcoded since we can't include the various // header files where they are defined (e.g., fdd.h, mo.h). // However, all in ui::MediaType support 4 except cassette. -int MediaHistoryManager::maxDevicesSupported(ui::MediaType type) +int +MediaHistoryManager::maxDevicesSupported(ui::MediaType type) { return type == ui::MediaType::Cassette ? 1 : 4; - } -void MediaHistoryManager::deserializeImageHistoryType(ui::MediaType type) +void +MediaHistoryManager::deserializeImageHistoryType(ui::MediaType type) { for (int device = 0; device < maxDevicesSupported(type); device++) { char **device_history_ptr = getEmuHistoryVarForType(type, device); - if(device_history_ptr == nullptr) { + if (device_history_ptr == nullptr) { // Device not supported, return and do not deserialize. // This will leave the image listing at the default initialization state // from the ui side (this class) continue; } - for ( int slot = 0; slot < MAX_PREV_IMAGES; slot++) { + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { master_list[type][device][slot] = device_history_ptr[slot]; } } } -void MediaHistoryManager::deserializeAllImageHistory() +void +MediaHistoryManager::deserializeAllImageHistory() { - for ( const auto device_type : ui::AllSupportedMediaHistoryTypes ) { + for (const auto device_type : ui::AllSupportedMediaHistoryTypes) { deserializeImageHistoryType(device_type); } } -void MediaHistoryManager::serializeImageHistoryType(ui::MediaType type) +void +MediaHistoryManager::serializeImageHistoryType(ui::MediaType type) { for (int device = 0; device < maxDevicesSupported(type); device++) { char **device_history_ptr = getEmuHistoryVarForType(type, device); - if(device_history_ptr == nullptr) { + if (device_history_ptr == nullptr) { // Device not supported, return and do not serialize. // This will leave the image listing at the current state, // and it will not be saved on the emu side continue; } - for ( int slot = 0; slot < MAX_PREV_IMAGES; slot++) { + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { if (device_history_ptr[slot] != nullptr) { strncpy(device_history_ptr[slot], master_list[type][device][slot].toUtf8().constData(), MAX_IMAGE_PATH_LEN); } @@ -144,19 +145,21 @@ void MediaHistoryManager::serializeImageHistoryType(ui::MediaType type) } } -void MediaHistoryManager::serializeAllImageHistory() +void +MediaHistoryManager::serializeAllImageHistory() { - for ( const auto device_type : ui::AllSupportedMediaHistoryTypes ) { + for (const auto device_type : ui::AllSupportedMediaHistoryTypes) { serializeImageHistoryType(device_type); } } -void MediaHistoryManager::initialDeduplication() +void +MediaHistoryManager::initialDeduplication() { QString current_image; // Perform initial dedup if an image is loaded - for ( const auto device_type : ui::AllSupportedMediaHistoryTypes ) { + for (const auto device_type : ui::AllSupportedMediaHistoryTypes) { for (int device_index = 0; device_index < maxDevicesSupported(device_type); device_index++) { device_index_list_t device_history = getHistoryListForDeviceIndex(device_index, device_type); switch (device_type) { @@ -170,10 +173,10 @@ void MediaHistoryManager::initialDeduplication() continue; break; } - deduplicateList(device_history, QVector (1, current_image)); + deduplicateList(device_history, QVector(1, current_image)); // Fill in missing, if any int missing = MAX_PREV_IMAGES - device_history.size(); - if(missing) { + if (missing) { for (int i = 0; i < missing; i++) { device_history.push_back(QString()); } @@ -183,7 +186,8 @@ void MediaHistoryManager::initialDeduplication() } } -char ** MediaHistoryManager::getEmuHistoryVarForType(ui::MediaType type, int index) +char ** +MediaHistoryManager::getEmuHistoryVarForType(ui::MediaType type, int index) { switch (type) { case ui::MediaType::Optical: @@ -192,24 +196,23 @@ char ** MediaHistoryManager::getEmuHistoryVarForType(ui::MediaType type, int ind return &fdd_image_history[index][0]; default: return nullptr; - } } device_index_list_t & -MediaHistoryManager::deduplicateList(device_index_list_t &device_history, const QVector& filenames) +MediaHistoryManager::deduplicateList(device_index_list_t &device_history, const QVector &filenames) { QVector items_to_delete; for (auto &list_item_path : device_history) { - if(list_item_path.isEmpty()) { - continue ; + if (list_item_path.isEmpty()) { + continue; } - for (const auto& path_to_check : filenames) { - if(path_to_check.isEmpty()) { - continue ; + for (const auto &path_to_check : filenames) { + if (path_to_check.isEmpty()) { + continue; } QString adjusted_path = pathAdjustSingle(path_to_check); - int match = QString::localeAwareCompare(list_item_path, adjusted_path); + int match = QString::localeAwareCompare(list_item_path, adjusted_path); if (match == 0) { items_to_delete.append(list_item_path); } @@ -217,22 +220,22 @@ MediaHistoryManager::deduplicateList(device_index_list_t &device_history, const } // Remove by name rather than index because the index would change // after each removal - for (const auto& path: items_to_delete) { + for (const auto &path : items_to_delete) { device_history.removeAll(path); } return device_history; } -void MediaHistoryManager::addImageToHistory(int index, ui::MediaType type, const QString& image_name, const QString& new_image_name) +void +MediaHistoryManager::addImageToHistory(int index, ui::MediaType type, const QString &image_name, const QString &new_image_name) { device_index_list_t device_history = getHistoryListForDeviceIndex(index, type); - QVector files_to_check; + QVector files_to_check; files_to_check.append(image_name); files_to_check.append(new_image_name); device_history = deduplicateList(device_history, files_to_check); - if (!image_name.isEmpty()) { device_history.push_front(image_name); } @@ -244,7 +247,7 @@ void MediaHistoryManager::addImageToHistory(int index, ui::MediaType type, const // Fill in missing, if any int missing = MAX_PREV_IMAGES - device_history.size(); - if(missing) { + if (missing) { for (int i = 0; i < missing; i++) { device_history.push_back(QString()); } @@ -257,7 +260,8 @@ void MediaHistoryManager::addImageToHistory(int index, ui::MediaType type, const serializeImageHistoryType(type); } -QString MediaHistoryManager::mediaTypeToString(ui::MediaType type) +QString +MediaHistoryManager::mediaTypeToString(ui::MediaType type) { QMetaEnum qme = QMetaEnum::fromType(); return qme.valueToKey(static_cast(type)); @@ -266,7 +270,7 @@ QString MediaHistoryManager::mediaTypeToString(ui::MediaType type) QString MediaHistoryManager::pathAdjustSingle(QString checked_path) { - QString current_usr_path = getUsrPath(); + QString current_usr_path = getUsrPath(); QFileInfo file_info(checked_path); if (file_info.filePath().isEmpty() || current_usr_path.isEmpty() || file_info.isRelative()) { return checked_path; @@ -285,7 +289,8 @@ MediaHistoryManager::pathAdjustFull(device_index_list_t &device_history) } return device_history; } -QString MediaHistoryManager::getUsrPath() +QString +MediaHistoryManager::getUsrPath() { QString current_usr_path(usr_path); // Ensure `usr_path` has a trailing slash @@ -301,7 +306,7 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) } // For this check, explicitly prepend `usr_path` to relative paths to account for $CWD platform variances QFileInfo absolute_path = file_info.isRelative() ? QFileInfo(getUsrPath().append(file_info.filePath())) : file_info; - if(!absolute_path.exists()) { + if (!absolute_path.exists()) { qWarning("Image file %s does not exist - removing from history", qPrintable(file_info.filePath())); checked_path = ""; } @@ -309,7 +314,8 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) return device_history; } -void MediaHistoryManager::initializeImageHistory() +void +MediaHistoryManager::initializeImageHistory() { auto initial_master_list = getMasterList(); setMasterList(blankImageHistory(initial_master_list)); diff --git a/src/qt/qt_mediahistorymanager.hpp b/src/qt/qt_mediahistorymanager.hpp index c628ce793..507cbdf7f 100644 --- a/src/qt/qt_mediahistorymanager.hpp +++ b/src/qt/qt_mediahistorymanager.hpp @@ -1,19 +1,19 @@ /* -* 86Box A hypervisor and IBM PC system emulator that specializes in -* running old operating systems and software designed for IBM -* PC systems and compatibles from 1981 through fairly recent -* system designs based on the PCI bus. -* -* This file is part of the 86Box distribution. -* -* Header for the media history management module -* -* -* -* Authors: cold-brewed -* -* Copyright 2022 The 86Box development team -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header for the media history management module + * + * + * + * Authors: cold-brewed + * + * Copyright 2022 The 86Box development team + */ #ifndef QT_MEDIAHISTORYMANAGER_HPP #define QT_MEDIAHISTORYMANAGER_HPP @@ -30,110 +30,109 @@ extern "C" { // This macro helps give us the required `qHash()` function in order to use the // enum as a hash key -#define QHASH_FOR_CLASS_ENUM(T) \ -inline uint qHash(const T &t, uint seed) { \ - return ::qHash(static_cast::type>(t), seed); \ -} +#define QHASH_FOR_CLASS_ENUM(T) \ + inline uint qHash(const T &t, uint seed) \ + { \ + return ::qHash(static_cast::type>(t), seed); \ + } typedef QVector device_index_list_t; typedef QHash> device_media_history_t; - namespace ui { - Q_NAMESPACE - - enum class MediaType { - Floppy, - Optical, - Zip, - Mo, - Cassette - }; - // This macro allows us to do a reverse lookup of the enum with `QMetaEnum` - Q_ENUM_NS(MediaType) - - QHASH_FOR_CLASS_ENUM(MediaType) +Q_NAMESPACE - typedef QHash master_list_t; +enum class MediaType { + Floppy, + Optical, + Zip, + Mo, + Cassette +}; +// This macro allows us to do a reverse lookup of the enum with `QMetaEnum` +Q_ENUM_NS(MediaType) - // Used to iterate over all supported types when preparing data structures - // Also useful to indicate which types support history - static const MediaType AllSupportedMediaHistoryTypes[] = { - MediaType::Optical, - MediaType::Floppy, - }; +QHASH_FOR_CLASS_ENUM(MediaType) - class MediaHistoryManager { +typedef QHash master_list_t; - public: - MediaHistoryManager(); - virtual ~MediaHistoryManager(); +// Used to iterate over all supported types when preparing data structures +// Also useful to indicate which types support history +static const MediaType AllSupportedMediaHistoryTypes[] = { + MediaType::Optical, + MediaType::Floppy, +}; - // Get the image name for a particular slot, - // index, and type combination - QString getImageForSlot(int index, int slot, ui::MediaType type); +class MediaHistoryManager { - // Add an image to history - void addImageToHistory(int index, ui::MediaType type, const QString& image_name, const QString& new_image_name); +public: + MediaHistoryManager(); + virtual ~MediaHistoryManager(); - // Convert the enum value to a string - static QString mediaTypeToString(ui::MediaType type); + // Get the image name for a particular slot, + // index, and type combination + QString getImageForSlot(int index, int slot, ui::MediaType type); - // Clear out the image history - void clearImageHistory(); + // Add an image to history + void addImageToHistory(int index, ui::MediaType type, const QString &image_name, const QString &new_image_name); + // Convert the enum value to a string + static QString mediaTypeToString(ui::MediaType type); - private: - int max_images = MAX_PREV_IMAGES; + // Clear out the image history + void clearImageHistory(); - // Main hash of hash of vector of strings - master_list_t master_list; - [[nodiscard]] const master_list_t &getMasterList() const; - void setMasterList(const master_list_t &masterList); +private: + int max_images = MAX_PREV_IMAGES; - device_index_list_t index_list, empty_device_index_list; + // Main hash of hash of vector of strings + master_list_t master_list; + [[nodiscard]] const master_list_t &getMasterList() const; + void setMasterList(const master_list_t &masterList); - // Return a blank, initialized image history list - master_list_t &blankImageHistory(master_list_t &initialized_master_list) const; + device_index_list_t index_list, empty_device_index_list; - // Initialize the image history - void initializeImageHistory(); + // Return a blank, initialized image history list + master_list_t &blankImageHistory(master_list_t &initialized_master_list) const; - // Max number of devices supported by media type - static int maxDevicesSupported(ui::MediaType type); + // Initialize the image history + void initializeImageHistory(); - // Serialize the data back into the C array - // on the emu side - void serializeImageHistoryType(ui::MediaType type); - void serializeAllImageHistory(); + // Max number of devices supported by media type + static int maxDevicesSupported(ui::MediaType type); - // Deserialize the data from C array on the emu side - // for the ui side - void deserializeImageHistoryType(ui::MediaType type); - void deserializeAllImageHistory(); + // Serialize the data back into the C array + // on the emu side + void serializeImageHistoryType(ui::MediaType type); + void serializeAllImageHistory(); - // Get emu history variable for a device type - static char** getEmuHistoryVarForType(ui::MediaType type, int index); + // Deserialize the data from C array on the emu side + // for the ui side + void deserializeImageHistoryType(ui::MediaType type); + void deserializeAllImageHistory(); - // Get or set the history for a specific device/index combo - const device_index_list_t &getHistoryListForDeviceIndex(int index, ui::MediaType type); - void setHistoryListForDeviceIndex(int index, ui::MediaType type, device_index_list_t history_list); + // Get emu history variable for a device type + static char **getEmuHistoryVarForType(ui::MediaType type, int index); - // Remove missing image files from history list - static device_index_list_t &removeMissingImages(device_index_list_t &device_history); + // Get or set the history for a specific device/index combo + const device_index_list_t &getHistoryListForDeviceIndex(int index, ui::MediaType type); + void setHistoryListForDeviceIndex(int index, ui::MediaType type, device_index_list_t history_list); - // If an absolute path is contained within `usr_path`, convert to a relative path - static device_index_list_t &pathAdjustFull(device_index_list_t &device_history); - static QString pathAdjustSingle(QString checked_path); + // Remove missing image files from history list + static device_index_list_t &removeMissingImages(device_index_list_t &device_history); - // Deduplicate history entries - static device_index_list_t &deduplicateList(device_index_list_t &device_history, const QVector& filenames); - void initialDeduplication(); + // If an absolute path is contained within `usr_path`, convert to a relative path + static device_index_list_t &pathAdjustFull(device_index_list_t &device_history); + static QString pathAdjustSingle(QString checked_path); - // Gets the `usr_path` from the emu side and appends a - // trailing slash if necessary - static QString getUsrPath(); - }; + // Deduplicate history entries + static device_index_list_t &deduplicateList(device_index_list_t &device_history, const QVector &filenames); + void initialDeduplication(); + + // Gets the `usr_path` from the emu side and appends a + // trailing slash if necessary + static QString getUsrPath(); +}; } // ui diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 560249660..e0c145981 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -47,7 +47,6 @@ extern "C" { #include <86box/ui.h> #include <86box/thread.h> #include <86box/network.h> - }; #include "qt_newfloppydialog.hpp" @@ -58,14 +57,18 @@ extern "C" { std::shared_ptr MediaMenu::ptr; -MediaMenu::MediaMenu(QWidget* parent) : QObject(parent) { +MediaMenu::MediaMenu(QWidget *parent) + : QObject(parent) +{ parentWidget = parent; } -void MediaMenu::refresh(QMenu *parentMenu) { +void +MediaMenu::refresh(QMenu *parentMenu) +{ parentMenu->clear(); - if(MachineStatus::hasCassette()) { + if (MachineStatus::hasCassette()) { cassetteMenu = parentMenu->addMenu(""); cassetteMenu->addAction(tr("&New image..."), [this]() { cassetteNewImage(); }); cassetteMenu->addSeparator(); @@ -88,8 +91,8 @@ void MediaMenu::refresh(QMenu *parentMenu) { cartridgeMenus.clear(); if (machine_has_cartridge(machine)) { - for(int i = 0; i < 2; i++) { - auto* menu = parentMenu->addMenu(""); + for (int i = 0; i < 2; i++) { + auto *menu = parentMenu->addMenu(""); menu->addAction(tr("&Image..."), [this, i]() { cartridgeSelectImage(i); }); menu->addSeparator(); cartridgeEjectPos = menu->children().count(); @@ -101,7 +104,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { floppyMenus.clear(); MachineStatus::iterateFDD([this, parentMenu](int i) { - auto* menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); menu->addAction(tr("&New image..."), [this, i]() { floppyNewImage(i); }); menu->addSeparator(); menu->addAction(tr("&Existing image..."), [this, i]() { floppySelectImage(i, false); }); @@ -123,7 +126,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { cdromMenus.clear(); MachineStatus::iterateCDROM([this, parentMenu](int i) { - auto* menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); cdromMutePos = menu->children().count(); menu->addAction(QApplication::style()->standardIcon(QStyle::SP_MediaVolumeMuted), tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true); menu->addSeparator(); @@ -136,7 +139,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { } menu->addSeparator(); cdromImagePos = menu->children().count(); - cdromDirPos = menu->children().count(); + cdromDirPos = menu->children().count(); menu->addAction(tr("E&ject"), [this, i]() { cdromEject(i); })->setCheckable(false); cdromMenus[i] = menu; cdromUpdateMenu(i); @@ -144,7 +147,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { zipMenus.clear(); MachineStatus::iterateZIP([this, parentMenu](int i) { - auto* menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); menu->addAction(tr("&New image..."), [this, i]() { zipNewImage(i); }); menu->addSeparator(); menu->addAction(tr("&Existing image..."), [this, i]() { zipSelectImage(i, false); }); @@ -160,7 +163,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { moMenus.clear(); MachineStatus::iterateMO([this, parentMenu](int i) { - auto* menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); menu->addAction(tr("&New image..."), [this, i]() { moNewImage(i); }); menu->addSeparator(); menu->addAction(tr("&Existing image..."), [this, i]() { moSelectImage(i, false); }); @@ -176,9 +179,9 @@ void MediaMenu::refresh(QMenu *parentMenu) { netMenus.clear(); MachineStatus::iterateNIC([this, parentMenu](int i) { - auto *menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); netDisconnPos = menu->children().count(); - auto *action = menu->addAction(tr("&Connected"), [this, i] { network_is_connected(i) ? nicDisconnect(i) : nicConnect(i); }); + auto *action = menu->addAction(tr("&Connected"), [this, i] { network_is_connected(i) ? nicDisconnect(i) : nicConnect(i); }); action->setCheckable(true); netMenus[i] = menu; nicUpdateMenu(i); @@ -186,36 +189,42 @@ void MediaMenu::refresh(QMenu *parentMenu) { parentMenu->addAction(tr("Clear image history"), [this]() { clearImageHistory(); }); } -void MediaMenu::cassetteNewImage() { - auto filename = QFileDialog::getSaveFileName(parentWidget, tr("Create...")); +void +MediaMenu::cassetteNewImage() +{ + auto filename = QFileDialog::getSaveFileName(parentWidget, tr("Create...")); QFileInfo fileinfo(filename); if (fileinfo.suffix().isEmpty()) { filename.append(".cas"); } if (!filename.isNull()) { - if (filename.isEmpty()) cassetteEject(); - else cassetteMount(filename, false); + if (filename.isEmpty()) + cassetteEject(); + else + cassetteMount(filename, false); } } -void MediaMenu::cassetteSelectImage(bool wp) { +void +MediaMenu::cassetteSelectImage(bool wp) +{ auto filename = QFileDialog::getOpenFileName(parentWidget, - QString(), - getMediaOpenDirectory(), - tr("Cassette images") % - util::DlgFilter({ "pcm","raw","wav","cas" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + QString(), + getMediaOpenDirectory(), + tr("Cassette images") % util::DlgFilter({ "pcm", "raw", "wav", "cas" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - if (!filename.isEmpty()) cassetteMount(filename, wp); + if (!filename.isEmpty()) + cassetteMount(filename, wp); } -void MediaMenu::cassetteMount(const QString& filename, bool wp) { +void +MediaMenu::cassetteMount(const QString &filename, bool wp) +{ pc_cas_set_fname(cassette, nullptr); memset(cassette_fname, 0, sizeof(cassette_fname)); cassette_ui_writeprot = wp ? 1 : 0; - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); strncpy(cassette_fname, filenameBytes.data(), sizeof(cassette_fname) - 1); pc_cas_set_fname(cassette, cassette_fname); @@ -227,7 +236,9 @@ void MediaMenu::cassetteMount(const QString& filename, bool wp) { config_save(); } -void MediaMenu::cassetteEject() { +void +MediaMenu::cassetteEject() +{ pc_cas_set_fname(cassette, nullptr); memset(cassette_fname, 0, sizeof(cassette_fname)); ui_sb_update_icon_state(SB_CASSETTE, 1); @@ -236,15 +247,17 @@ void MediaMenu::cassetteEject() { config_save(); } -void MediaMenu::cassetteUpdateMenu() { - QString name = cassette_fname; - QString mode = cassette_mode; - auto childs = cassetteMenu->children(); - auto* recordMenu = dynamic_cast(childs[cassetteRecordPos]); - auto* playMenu = dynamic_cast(childs[cassettePlayPos]); - auto* rewindMenu = dynamic_cast(childs[cassetteRewindPos]); - auto* fastFwdMenu = dynamic_cast(childs[cassetteFastFwdPos]); - auto* ejectMenu = dynamic_cast(childs[cassetteEjectPos]); +void +MediaMenu::cassetteUpdateMenu() +{ + QString name = cassette_fname; + QString mode = cassette_mode; + auto childs = cassetteMenu->children(); + auto *recordMenu = dynamic_cast(childs[cassetteRecordPos]); + auto *playMenu = dynamic_cast(childs[cassettePlayPos]); + auto *rewindMenu = dynamic_cast(childs[cassetteRewindPos]); + auto *fastFwdMenu = dynamic_cast(childs[cassetteFastFwdPos]); + auto *ejectMenu = dynamic_cast(childs[cassetteEjectPos]); recordMenu->setEnabled(!name.isEmpty()); playMenu->setEnabled(!name.isEmpty()); @@ -254,12 +267,13 @@ void MediaMenu::cassetteUpdateMenu() { bool isSaving = mode == QStringLiteral("save"); recordMenu->setChecked(isSaving); - playMenu->setChecked(! isSaving); + playMenu->setChecked(!isSaving); cassetteMenu->setTitle(QString::asprintf(tr("Cassette: %s").toUtf8().constData(), (name.isEmpty() ? tr("(empty)") : name).toUtf8().constData())); } -void MediaMenu::cartridgeMount(int i, const QString &filename) +void +MediaMenu::cartridgeMount(int i, const QString &filename) { cart_close(i); QByteArray filenameBytes = filename.toUtf8(); @@ -271,15 +285,14 @@ void MediaMenu::cartridgeMount(int i, const QString &filename) config_save(); } -void MediaMenu::cartridgeSelectImage(int i) { +void +MediaMenu::cartridgeSelectImage(int i) +{ auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), getMediaOpenDirectory(), - tr("Cartridge images") % - util::DlgFilter({ "a","b","jrc" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + tr("Cartridge images") % util::DlgFilter({ "a", "b", "jrc" }) % tr("All files") % util::DlgFilter({ "*" }, true)); if (filename.isEmpty()) { return; @@ -287,7 +300,9 @@ void MediaMenu::cartridgeSelectImage(int i) { cartridgeMount(i, filename); } -void MediaMenu::cartridgeEject(int i) { +void +MediaMenu::cartridgeEject(int i) +{ cart_close(i); ui_sb_update_icon_state(SB_CARTRIDGE | i, 1); cartridgeUpdateMenu(i); @@ -295,27 +310,33 @@ void MediaMenu::cartridgeEject(int i) { config_save(); } -void MediaMenu::cartridgeUpdateMenu(int i) { - QString name = cart_fns[i]; - auto* menu = cartridgeMenus[i]; - auto childs = menu->children(); - auto* ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); +void +MediaMenu::cartridgeUpdateMenu(int i) +{ + QString name = cart_fns[i]; + auto *menu = cartridgeMenus[i]; + auto childs = menu->children(); + auto *ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); ejectMenu->setEnabled(!name.isEmpty()); - //menu->setTitle(tr("Cartridge %1: %2").arg(QString::number(i+1), name.isEmpty() ? tr("(empty)") : name)); + // menu->setTitle(tr("Cartridge %1: %2").arg(QString::number(i+1), name.isEmpty() ? tr("(empty)") : name)); menu->setTitle(QString::asprintf(tr("Cartridge %i: %ls").toUtf8().constData(), i + 1, name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } -void MediaMenu::floppyNewImage(int i) { +void +MediaMenu::floppyNewImage(int i) +{ NewFloppyDialog dialog(NewFloppyDialog::MediaType::Floppy, parentWidget); switch (dialog.exec()) { - case QDialog::Accepted: - QByteArray filename = dialog.fileName().toUtf8(); - floppyMount(i, filename, false); - break; + case QDialog::Accepted: + QByteArray filename = dialog.fileName().toUtf8(); + floppyMount(i, filename, false); + break; } } -void MediaMenu::floppySelectImage(int i, bool wp) { +void +MediaMenu::floppySelectImage(int i, bool wp) +{ auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), @@ -336,11 +357,13 @@ void MediaMenu::floppySelectImage(int i, bool wp) { if (!filename.isEmpty()) floppyMount(i, filename, wp); } -void MediaMenu::floppyMount(int i, const QString &filename, bool wp) { +void +MediaMenu::floppyMount(int i, const QString &filename, bool wp) +{ auto previous_image = QFileInfo(floppyfns[i]); fdd_close(i); ui_writeprot[i] = wp ? 1 : 0; - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); fdd_load(i, filenameBytes.data()); } @@ -351,7 +374,9 @@ void MediaMenu::floppyMount(int i, const QString &filename, bool wp) { config_save(); } -void MediaMenu::floppyEject(int i) { +void +MediaMenu::floppyEject(int i) +{ mhm.addImageToHistory(i, ui::MediaType::Floppy, floppyfns[i], QString()); fdd_close(i); ui_sb_update_icon_state(SB_FLOPPY | i, 1); @@ -360,9 +385,11 @@ void MediaMenu::floppyEject(int i) { config_save(); } -void MediaMenu::floppyExportTo86f(int i) { +void +MediaMenu::floppyExportTo86f(int i) +{ auto filename = QFileDialog::getSaveFileName(parentWidget, QString(), QString(), tr("Surface images") % util::DlgFilter({ "86f" }, true)); - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); plat_pause(1); if (d86f_export(i, filenameBytes.data()) == 0) { @@ -372,20 +399,22 @@ void MediaMenu::floppyExportTo86f(int i) { } } -void MediaMenu::floppyUpdateMenu(int i) { - QString name = floppyfns[i]; +void +MediaMenu::floppyUpdateMenu(int i) +{ + QString name = floppyfns[i]; QFileInfo fi(floppyfns[i]); if (!floppyMenus.contains(i)) return; - auto* menu = floppyMenus[i]; - auto childs = menu->children(); + auto *menu = floppyMenus[i]; + auto childs = menu->children(); - auto* ejectMenu = dynamic_cast(childs[floppyEjectPos]); - auto* exportMenu = dynamic_cast(childs[floppyExportPos]); + auto *ejectMenu = dynamic_cast(childs[floppyEjectPos]); + auto *exportMenu = dynamic_cast(childs[floppyExportPos]); ejectMenu->setEnabled(!name.isEmpty()); - ejectMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData())); + ejectMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData())); exportMenu->setEnabled(!name.isEmpty()); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { @@ -393,25 +422,30 @@ void MediaMenu::floppyUpdateMenu(int i) { } int type = fdd_get_type(i); - //floppyMenus[i]->setTitle(tr("Floppy %1 (%2): %3").arg(QString::number(i+1), fdd_getname(type), name.isEmpty() ? tr("(empty)") : name)); + // floppyMenus[i]->setTitle(tr("Floppy %1 (%2): %3").arg(QString::number(i+1), fdd_getname(type), name.isEmpty() ? tr("(empty)") : name)); floppyMenus[i]->setTitle(QString::asprintf(tr("Floppy %i (%s): %ls").toUtf8().constData(), i + 1, fdd_getname(type), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } -void MediaMenu::floppyMenuSelect(int index, int slot) { +void +MediaMenu::floppyMenuSelect(int index, int slot) +{ QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Floppy); floppyMount(index, filename.toUtf8().constData(), false); floppyUpdateMenu(index); ui_sb_update_tip(SB_FLOPPY | index); } -void MediaMenu::cdromMute(int i) { +void +MediaMenu::cdromMute(int i) +{ cdrom[i].sound_on ^= 1; config_save(); cdromUpdateMenu(i); sound_cd_thread_reset(); } -void MediaMenu::cdromMount(int i, const QString &filename) +void +MediaMenu::cdromMount(int i, const QString &filename) { QByteArray fn = filename.toUtf8().data(); @@ -438,8 +472,10 @@ void MediaMenu::cdromMount(int i, const QString &filename) config_save(); } -void MediaMenu::cdromMount(int i, int dir) { - QString filename; +void +MediaMenu::cdromMount(int i, int dir) +{ + QString filename; QFileInfo fi(cdrom[i].image_path); if (dir) { @@ -450,10 +486,7 @@ void MediaMenu::cdromMount(int i, int dir) { parentWidget, QString(), QString(), - tr("CD-ROM images") % - util::DlgFilter({ "iso","cue" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + tr("CD-ROM images") % util::DlgFilter({ "iso", "cue" }) % tr("All files") % util::DlgFilter({ "*" }, true)); } if (filename.isEmpty()) { @@ -463,34 +496,40 @@ void MediaMenu::cdromMount(int i, int dir) { cdromMount(i, filename); } -void MediaMenu::cdromEject(int i) { +void +MediaMenu::cdromEject(int i) +{ mhm.addImageToHistory(i, ui::MediaType::Optical, cdrom[i].image_path, QString()); cdrom_eject(i); cdromUpdateMenu(i); ui_sb_update_tip(SB_CDROM | i); } -void MediaMenu::cdromReload(int index, int slot) { +void +MediaMenu::cdromReload(int index, int slot) +{ QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Optical); cdromMount(index, filename.toUtf8().constData()); cdromUpdateMenu(index); ui_sb_update_tip(SB_CDROM | index); } -void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) { - QMenu* menu; - QAction* imageHistoryUpdatePos; +void +MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) +{ + QMenu *menu; + QAction *imageHistoryUpdatePos; QObjectList children; - QFileInfo fi; - QIcon menu_icon; + QFileInfo fi; + QIcon menu_icon; switch (type) { case ui::MediaType::Optical: if (!cdromMenus.contains(index)) return; - menu = cdromMenus[index]; - children = menu->children(); - imageHistoryUpdatePos = dynamic_cast(children[cdromImageHistoryPos[slot]]); + menu = cdromMenus[index]; + children = menu->children(); + imageHistoryUpdatePos = dynamic_cast(children[cdromImageHistoryPos[slot]]); fi.setFile(mhm.getImageForSlot(index, slot, type)); menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); imageHistoryUpdatePos->setIcon(menu_icon); @@ -498,9 +537,9 @@ void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) { case ui::MediaType::Floppy: if (!floppyMenus.contains(index)) return; - menu = floppyMenus[index]; - children = menu->children(); - imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); + menu = floppyMenus[index]; + children = menu->children(); + imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); fi.setFile(mhm.getImageForSlot(index, slot, type)); break; default: @@ -511,29 +550,34 @@ void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) { QString menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); imageHistoryUpdatePos->setText(QString::asprintf(tr("%s").toUtf8().constData(), menu_item_name.toUtf8().constData())); imageHistoryUpdatePos->setVisible(!fi.fileName().isEmpty()); + imageHistoryUpdatePos->setVisible(fi.exists()); } -void MediaMenu::clearImageHistory() { +void +MediaMenu::clearImageHistory() +{ mhm.clearImageHistory(); ui_sb_update_panes(); } -void MediaMenu::cdromUpdateMenu(int i) { - QString name = cdrom[i].image_path; +void +MediaMenu::cdromUpdateMenu(int i) +{ + QString name = cdrom[i].image_path; QFileInfo fi(cdrom[i].image_path); if (!cdromMenus.contains(i)) return; - auto* menu = cdromMenus[i]; - auto childs = menu->children(); + auto *menu = cdromMenus[i]; + auto childs = menu->children(); - auto* muteMenu = dynamic_cast(childs[cdromMutePos]); + auto *muteMenu = dynamic_cast(childs[cdromMutePos]); muteMenu->setChecked(cdrom[i].sound_on == 0); - auto* imageMenu = dynamic_cast(childs[cdromImagePos]); + auto *imageMenu = dynamic_cast(childs[cdromImagePos]); imageMenu->setEnabled(!name.isEmpty()); QString menu_item_name = name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData(); - auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); + auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); imageMenu->setIcon(menu_icon); imageMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), menu_item_name.toUtf8().constData())); @@ -543,47 +587,51 @@ void MediaMenu::cdromUpdateMenu(int i) { QString busName = tr("Unknown Bus"); switch (cdrom[i].bus_type) { - case CDROM_BUS_ATAPI: - busName = "ATAPI"; - break; - case CDROM_BUS_SCSI: - busName = "SCSI"; - break; + case CDROM_BUS_ATAPI: + busName = "ATAPI"; + break; + case CDROM_BUS_SCSI: + busName = "SCSI"; + break; } - //menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); + // menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); menu->setTitle(QString::asprintf(tr("CD-ROM %i (%s): %s").toUtf8().constData(), i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toUtf8().data() : name.toUtf8().data())); } -void MediaMenu::zipNewImage(int i) { +void +MediaMenu::zipNewImage(int i) +{ NewFloppyDialog dialog(NewFloppyDialog::MediaType::Zip, parentWidget); switch (dialog.exec()) { - case QDialog::Accepted: - QByteArray filename = dialog.fileName().toUtf8(); - zipMount(i, filename, false); - break; + case QDialog::Accepted: + QByteArray filename = dialog.fileName().toUtf8(); + zipMount(i, filename, false); + break; } } -void MediaMenu::zipSelectImage(int i, bool wp) { +void +MediaMenu::zipSelectImage(int i, bool wp) +{ auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), QString(), - tr("ZIP images") % - util::DlgFilter({ "im?","zdi" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + tr("ZIP images") % util::DlgFilter({ "im?", "zdi" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - if (!filename.isEmpty()) zipMount(i, filename, wp); + if (!filename.isEmpty()) + zipMount(i, filename, wp); } -void MediaMenu::zipMount(int i, const QString &filename, bool wp) { +void +MediaMenu::zipMount(int i, const QString &filename, bool wp) +{ zip_t *dev = (zip_t *) zip_drives[i].priv; zip_disk_close(dev); zip_drives[i].read_only = wp; - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); zip_load(dev, filenameBytes.data()); zip_insert(dev); @@ -596,7 +644,9 @@ void MediaMenu::zipMount(int i, const QString &filename, bool wp) { config_save(); } -void MediaMenu::zipEject(int i) { +void +MediaMenu::zipEject(int i) +{ zip_t *dev = (zip_t *) zip_drives[i].priv; zip_disk_close(dev); @@ -612,78 +662,89 @@ void MediaMenu::zipEject(int i) { config_save(); } -void MediaMenu::zipReload(int i) { +void +MediaMenu::zipReload(int i) +{ zip_t *dev = (zip_t *) zip_drives[i].priv; zip_disk_reload(dev); if (strlen(zip_drives[i].image_path) == 0) { - ui_sb_update_icon_state(SB_ZIP|i, 1); + ui_sb_update_icon_state(SB_ZIP | i, 1); } else { - ui_sb_update_icon_state(SB_ZIP|i, 0); + ui_sb_update_icon_state(SB_ZIP | i, 0); } zipUpdateMenu(i); - ui_sb_update_tip(SB_ZIP|i); + ui_sb_update_tip(SB_ZIP | i); config_save(); } -void MediaMenu::zipUpdateMenu(int i) { - QString name = zip_drives[i].image_path; +void +MediaMenu::zipUpdateMenu(int i) +{ + QString name = zip_drives[i].image_path; QString prev_name = zip_drives[i].prev_image_path; if (!zipMenus.contains(i)) return; - auto* menu = zipMenus[i]; - auto childs = menu->children(); + auto *menu = zipMenus[i]; + auto childs = menu->children(); - auto* ejectMenu = dynamic_cast(childs[zipEjectPos]); - auto* reloadMenu = dynamic_cast(childs[zipReloadPos]); + auto *ejectMenu = dynamic_cast(childs[zipEjectPos]); + auto *reloadMenu = dynamic_cast(childs[zipReloadPos]); ejectMenu->setEnabled(!name.isEmpty()); reloadMenu->setEnabled(!prev_name.isEmpty()); QString busName = tr("Unknown Bus"); switch (zip_drives[i].bus_type) { - case ZIP_BUS_ATAPI: - busName = "ATAPI"; - break; - case ZIP_BUS_SCSI: - busName = "SCSI"; - break; + case ZIP_BUS_ATAPI: + busName = "ATAPI"; + break; + case ZIP_BUS_SCSI: + busName = "SCSI"; + break; } - //menu->setTitle(tr("ZIP %1 %2 (%3): %4").arg((zip_drives[i].is_250 > 0) ? "250" : "100", QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); + // menu->setTitle(tr("ZIP %1 %2 (%3): %4").arg((zip_drives[i].is_250 > 0) ? "250" : "100", QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); menu->setTitle(QString::asprintf(tr("ZIP %03i %i (%s): %ls").toUtf8().constData(), (zip_drives[i].is_250 > 0) ? 250 : 100, i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } -void MediaMenu::moNewImage(int i) { +void +MediaMenu::moNewImage(int i) +{ NewFloppyDialog dialog(NewFloppyDialog::MediaType::Mo, parentWidget); switch (dialog.exec()) { - case QDialog::Accepted: - QByteArray filename = dialog.fileName().toUtf8(); - moMount(i, filename, false); - break; + case QDialog::Accepted: + QByteArray filename = dialog.fileName().toUtf8(); + moMount(i, filename, false); + break; } } -void MediaMenu::moSelectImage(int i, bool wp) { +void +MediaMenu::moSelectImage(int i, bool wp) +{ auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), getMediaOpenDirectory(), - tr("MO images") % - util::DlgFilter({ "im?", "mdi" }) % - tr("All files") % - util::DlgFilter({ "*", }, true)); + tr("MO images") % util::DlgFilter({ "im?", "mdi" }) % tr("All files") % util::DlgFilter({ + "*", + }, + true)); - if (!filename.isEmpty()) moMount(i, filename, wp); + if (!filename.isEmpty()) + moMount(i, filename, wp); } -void MediaMenu::moMount(int i, const QString &filename, bool wp) { +void +MediaMenu::moMount(int i, const QString &filename, bool wp) +{ mo_t *dev = (mo_t *) mo_drives[i].priv; mo_disk_close(dev); mo_drives[i].read_only = wp; - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); mo_load(dev, filenameBytes.data()); mo_insert(dev); @@ -696,7 +757,9 @@ void MediaMenu::moMount(int i, const QString &filename, bool wp) { config_save(); } -void MediaMenu::moEject(int i) { +void +MediaMenu::moEject(int i) +{ mo_t *dev = (mo_t *) mo_drives[i].priv; mo_disk_close(dev); @@ -712,63 +775,73 @@ void MediaMenu::moEject(int i) { config_save(); } -void MediaMenu::moReload(int i) { +void +MediaMenu::moReload(int i) +{ mo_t *dev = (mo_t *) mo_drives[i].priv; mo_disk_reload(dev); if (strlen(mo_drives[i].image_path) == 0) { - ui_sb_update_icon_state(SB_MO|i, 1); + ui_sb_update_icon_state(SB_MO | i, 1); } else { - ui_sb_update_icon_state(SB_MO|i, 0); + ui_sb_update_icon_state(SB_MO | i, 0); } moUpdateMenu(i); - ui_sb_update_tip(SB_MO|i); + ui_sb_update_tip(SB_MO | i); config_save(); } -void MediaMenu::moUpdateMenu(int i) { - QString name = mo_drives[i].image_path; +void +MediaMenu::moUpdateMenu(int i) +{ + QString name = mo_drives[i].image_path; QString prev_name = mo_drives[i].prev_image_path; if (!moMenus.contains(i)) return; - auto* menu = moMenus[i]; - auto childs = menu->children(); + auto *menu = moMenus[i]; + auto childs = menu->children(); - auto* ejectMenu = dynamic_cast(childs[moEjectPos]); - auto* reloadMenu = dynamic_cast(childs[moReloadPos]); + auto *ejectMenu = dynamic_cast(childs[moEjectPos]); + auto *reloadMenu = dynamic_cast(childs[moReloadPos]); ejectMenu->setEnabled(!name.isEmpty()); reloadMenu->setEnabled(!prev_name.isEmpty()); QString busName = tr("Unknown Bus"); switch (mo_drives[i].bus_type) { - case MO_BUS_ATAPI: - busName = "ATAPI"; - break; - case MO_BUS_SCSI: - busName = "SCSI"; - break; + case MO_BUS_ATAPI: + busName = "ATAPI"; + break; + case MO_BUS_SCSI: + busName = "SCSI"; + break; } menu->setTitle(QString::asprintf(tr("MO %i (%ls): %ls").toUtf8().constData(), i + 1, busName.toStdU16String().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } -void MediaMenu::nicConnect(int i) { +void +MediaMenu::nicConnect(int i) +{ network_connect(i, 1); - ui_sb_update_icon_state(SB_NETWORK|i, 0); + ui_sb_update_icon_state(SB_NETWORK | i, 0); nicUpdateMenu(i); config_save(); } -void MediaMenu::nicDisconnect(int i) { +void +MediaMenu::nicDisconnect(int i) +{ network_connect(i, 0); - ui_sb_update_icon_state(SB_NETWORK|i, 1); + ui_sb_update_icon_state(SB_NETWORK | i, 1); nicUpdateMenu(i); config_save(); } -void MediaMenu::nicUpdateMenu(int i) { +void +MediaMenu::nicUpdateMenu(int i) +{ if (!netMenus.contains(i)) return; @@ -784,15 +857,17 @@ void MediaMenu::nicUpdateMenu(int i) { QString devName = DeviceConfig::DeviceName(network_card_getdevice(net_cards_conf[i].device_num), network_card_get_internal_name(net_cards_conf[i].device_num), 1); - auto *menu = netMenus[i]; - auto childs = menu->children(); - auto *connectedAction = dynamic_cast(childs[netDisconnPos]); + auto *menu = netMenus[i]; + auto childs = menu->children(); + auto *connectedAction = dynamic_cast(childs[netDisconnPos]); connectedAction->setChecked(network_is_connected(i)); menu->setTitle(QString::asprintf(tr("NIC %02i (%ls) %ls").toUtf8().constData(), i + 1, netType.toStdU16String().data(), devName.toStdU16String().data())); } -QString MediaMenu::getMediaOpenDirectory() { +QString +MediaMenu::getMediaOpenDirectory() +{ QString openDirectory; if (open_dir_usr_path > 0) { openDirectory = QString::fromUtf8(usr_path); @@ -803,20 +878,27 @@ QString MediaMenu::getMediaOpenDirectory() { // callbacks from 86box C code extern "C" { -void zip_eject(uint8_t id) { +void +zip_eject(uint8_t id) +{ MediaMenu::ptr->zipEject(id); } -void zip_reload(uint8_t id) { +void +zip_reload(uint8_t id) +{ MediaMenu::ptr->zipReload(id); } -void mo_eject(uint8_t id) { +void +mo_eject(uint8_t id) +{ MediaMenu::ptr->moEject(id); } -void mo_reload(uint8_t id) { +void +mo_reload(uint8_t id) +{ MediaMenu::ptr->moReload(id); } - } diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 4cb177797..57fd8dfc2 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -10,13 +10,12 @@ extern "C" { } class QMenu; -class MediaMenu : QObject -{ +class MediaMenu : QObject { Q_OBJECT public: - MediaMenu(QWidget* parent); + MediaMenu(QWidget *parent); - void refresh(QMenu* parentMenu); + void refresh(QMenu *parentMenu); // because some 86box C-only code needs to call zip and // mo eject directly @@ -24,18 +23,18 @@ public: void cassetteNewImage(); void cassetteSelectImage(bool wp); - void cassetteMount(const QString& filename, bool wp); + void cassetteMount(const QString &filename, bool wp); void cassetteEject(); void cassetteUpdateMenu(); void cartridgeSelectImage(int i); - void cartridgeMount(int i, const QString& filename); + void cartridgeMount(int i, const QString &filename); void cartridgeEject(int i); void cartridgeUpdateMenu(int i); void floppyNewImage(int i); void floppySelectImage(int i, bool wp); - void floppyMount(int i, const QString& filename, bool wp); + void floppyMount(int i, const QString &filename, bool wp); void floppyEject(int i); void floppyMenuSelect(int index, int slot); void floppyExportTo86f(int i); @@ -43,7 +42,7 @@ public: void cdromMute(int i); void cdromMount(int i, int dir); - void cdromMount(int i, const QString& filename); + void cdromMount(int i, const QString &filename); void cdromEject(int i); void cdromReload(int index, int slot); void updateImageHistory(int index, int slot, ui::MediaType type); @@ -52,14 +51,14 @@ public: void zipNewImage(int i); void zipSelectImage(int i, bool wp); - void zipMount(int i, const QString& filename, bool wp); + void zipMount(int i, const QString &filename, bool wp); void zipEject(int i); void zipReload(int i); void zipUpdateMenu(int i); void moNewImage(int i); void moSelectImage(int i, bool wp); - void moMount(int i, const QString& filename, bool wp); + void moMount(int i, const QString &filename, bool wp); void moEject(int i); void moReload(int i); void moUpdateMenu(int i); @@ -67,18 +66,19 @@ public: void nicConnect(int i); void nicDisconnect(int i); void nicUpdateMenu(int i); + private: - QWidget* parentWidget = nullptr; + QWidget *parentWidget = nullptr; - QMenu* cassetteMenu = nullptr; - QMap cartridgeMenus; - QMap floppyMenus; - QMap cdromMenus; - QMap zipMenus; - QMap moMenus; - QMap netMenus; + QMenu *cassetteMenu = nullptr; + QMap cartridgeMenus; + QMap floppyMenus; + QMap cdromMenus; + QMap zipMenus; + QMap moMenus; + QMap netMenus; - QString getMediaOpenDirectory(); + QString getMediaOpenDirectory(); ui::MediaHistoryManager mhm; int cassetteRecordPos; diff --git a/src/qt/qt_midi.cpp b/src/qt/qt_midi.cpp index a9b741c9e..2ea8ad3b1 100644 --- a/src/qt/qt_midi.cpp +++ b/src/qt/qt_midi.cpp @@ -2,43 +2,65 @@ extern "C" { -void plat_midi_play_msg(uint8_t *msg) -{} +void +plat_midi_play_msg(uint8_t *msg) +{ +} -void plat_midi_play_sysex(uint8_t *sysex, unsigned int len) -{} +void +plat_midi_play_sysex(uint8_t *sysex, unsigned int len) +{ +} -void plat_midi_input_init(void) -{} +void +plat_midi_input_init(void) +{ +} -void plat_midi_input_close(void) -{} +void +plat_midi_input_close(void) +{ +} -int plat_midi_write(uint8_t val) -{ return 0; } +int +plat_midi_write(uint8_t val) +{ + return 0; +} -void plat_midi_init() -{} +void +plat_midi_init() +{ +} -void plat_midi_close() -{} +void +plat_midi_close() +{ +} -int plat_midi_get_num_devs() -{ return 0; } +int +plat_midi_get_num_devs() +{ + return 0; +} -int plat_midi_in_get_num_devs(void) -{ return 0; } +int +plat_midi_in_get_num_devs(void) +{ + return 0; +} -void plat_midi_get_dev_name(int num, char *s) +void +plat_midi_get_dev_name(int num, char *s) { s[0] = ' '; s[1] = 0; } -void plat_midi_in_get_dev_name(int num, char *s) +void +plat_midi_in_get_dev_name(int num, char *s) { s[0] = ' '; s[1] = 0; } - } diff --git a/src/qt/qt_models_common.cpp b/src/qt/qt_models_common.cpp index eaa14bc0d..0e9856a50 100644 --- a/src/qt/qt_models_common.cpp +++ b/src/qt/qt_models_common.cpp @@ -18,7 +18,8 @@ #include -int Models::AddEntry(QAbstractItemModel *model, const QString& displayRole, int userRole) +int +Models::AddEntry(QAbstractItemModel *model, const QString &displayRole, int userRole) { int row = model->rowCount(); model->insertRow(row); diff --git a/src/qt/qt_models_common.hpp b/src/qt/qt_models_common.hpp index 91cda3836..98674a68f 100644 --- a/src/qt/qt_models_common.hpp +++ b/src/qt/qt_models_common.hpp @@ -2,7 +2,6 @@ class QString; class QAbstractItemModel; -namespace Models -{ - int AddEntry(QAbstractItemModel* model, const QString& displayRole, int userRole); +namespace Models { +int AddEntry(QAbstractItemModel *model, const QString &displayRole, int userRole); }; diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index 1581c6e52..1cb81d2ce 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -49,8 +49,8 @@ struct disk_size_t { int encoding; int rpm; int tracks; - int sectors; /* For IMG and Japanese FDI only. */ - int sector_len; /* For IMG and Japanese FDI only. */ + int sectors; /* For IMG and Japanese FDI only. */ + int sector_len; /* For IMG and Japanese FDI only. */ int media_desc; int spc; int num_fats; @@ -58,20 +58,22 @@ struct disk_size_t { int root_dir_entries; }; -static const disk_size_t disk_sizes[14] = { { 0, 1, 2, 1, 0, 40, 8, 2, 0xfe, 2, 2, 1, 64 }, /* 160k */ - { 0, 1, 2, 1, 0, 40, 9, 2, 0xfc, 2, 2, 1, 64 }, /* 180k */ - { 0, 2, 2, 1, 0, 40, 8, 2, 0xff, 2, 2, 1, 112 }, /* 320k */ - { 0, 2, 2, 1, 0, 40, 9, 2, 0xfd, 2, 2, 2, 112 }, /* 360k */ - { 0, 2, 2, 1, 0, 80, 8, 2, 0xfb, 2, 2, 2, 112 }, /* 640k */ - { 0, 2, 2, 1, 0, 80, 9, 2, 0xf9, 2, 2, 3, 112 }, /* 720k */ - { 1, 2, 0, 1, 1, 80, 15, 2, 0xf9, 1, 2, 7, 224 }, /* 1.2M */ - { 1, 2, 0, 1, 1, 77, 8, 3, 0xfe, 1, 2, 2, 192 }, /* 1.25M */ - { 1, 2, 0, 1, 0, 80, 18, 2, 0xf0, 1, 2, 9, 224 }, /* 1.44M */ - { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 2, 2, 5, 16 }, /* DMF cluster 1024 */ - { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 4, 2, 3, 16 }, /* DMF cluster 2048 */ - { 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240 }, /* 2.88M */ - { 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */ - { 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 } }; /* ZIP 250 */ +static const disk_size_t disk_sizes[14] = { + {0, 1, 2, 1, 0, 40, 8, 2, 0xfe, 2, 2, 1, 64 }, /* 160k */ + { 0, 1, 2, 1, 0, 40, 9, 2, 0xfc, 2, 2, 1, 64 }, /* 180k */ + { 0, 2, 2, 1, 0, 40, 8, 2, 0xff, 2, 2, 1, 112}, /* 320k */ + { 0, 2, 2, 1, 0, 40, 9, 2, 0xfd, 2, 2, 2, 112}, /* 360k */ + { 0, 2, 2, 1, 0, 80, 8, 2, 0xfb, 2, 2, 2, 112}, /* 640k */ + { 0, 2, 2, 1, 0, 80, 9, 2, 0xf9, 2, 2, 3, 112}, /* 720k */ + { 1, 2, 0, 1, 1, 80, 15, 2, 0xf9, 1, 2, 7, 224}, /* 1.2M */ + { 1, 2, 0, 1, 1, 77, 8, 3, 0xfe, 1, 2, 2, 192}, /* 1.25M */ + { 1, 2, 0, 1, 0, 80, 18, 2, 0xf0, 1, 2, 9, 224}, /* 1.44M */ + { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 2, 2, 5, 16 }, /* DMF cluster 1024 */ + { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 4, 2, 3, 16 }, /* DMF cluster 2048 */ + { 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240}, /* 2.88M */ + { 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */ + { 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 } +}; /* ZIP 250 */ static const QStringList rpmModes = { "Perfect RPM", @@ -113,41 +115,36 @@ static const QStringList moTypes = { "5.25\" 1.3 GB", }; -NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) : - QDialog(parent), - ui(new Ui::NewFloppyDialog), - mediaType_(type) +NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) + : QDialog(parent) + , ui(new Ui::NewFloppyDialog) + , mediaType_(type) { ui->setupUi(this); ui->fileField->setCreateFile(true); - auto* model = ui->comboBoxSize->model(); + auto *model = ui->comboBoxSize->model(); switch (type) { - case MediaType::Floppy: - for (int i = 0; i < floppyTypes.size(); ++i) { - Models::AddEntry(model, tr(floppyTypes[i].toUtf8().data()), i); - } - ui->fileField->setFilter( - tr("All images") % - util::DlgFilter({ "86f","dsk","flp","im?","*fd?" }) % - tr("Basic sector images") % - util::DlgFilter({ "dsk","flp","im?","img","*fd?" }) % - tr("Surface images") % - util::DlgFilter({ "86f" }, true)); + case MediaType::Floppy: + for (int i = 0; i < floppyTypes.size(); ++i) { + Models::AddEntry(model, tr(floppyTypes[i].toUtf8().data()), i); + } + ui->fileField->setFilter( + tr("All images") % util::DlgFilter({ "86f", "dsk", "flp", "im?", "*fd?" }) % tr("Basic sector images") % util::DlgFilter({ "dsk", "flp", "im?", "img", "*fd?" }) % tr("Surface images") % util::DlgFilter({ "86f" }, true)); - break; - case MediaType::Zip: - for (int i = 0; i < zipTypes.size(); ++i) { - Models::AddEntry(model, tr(zipTypes[i].toUtf8().data()), i); - } - ui->fileField->setFilter(tr("ZIP images") % util::DlgFilter({ "im?","zdi" }, true)); - break; - case MediaType::Mo: - for (int i = 0; i < moTypes.size(); ++i) { - Models::AddEntry(model, tr(moTypes[i].toUtf8().data()), i); - } - ui->fileField->setFilter(tr("MO images") % util::DlgFilter({ "im?","mdi" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - break; + break; + case MediaType::Zip: + for (int i = 0; i < zipTypes.size(); ++i) { + Models::AddEntry(model, tr(zipTypes[i].toUtf8().data()), i); + } + ui->fileField->setFilter(tr("ZIP images") % util::DlgFilter({ "im?", "zdi" }, true)); + break; + case MediaType::Mo: + for (int i = 0; i < moTypes.size(); ++i) { + Models::AddEntry(model, tr(moTypes[i].toUtf8().data()), i); + } + ui->fileField->setFilter(tr("MO images") % util::DlgFilter({ "im?", "mdi" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + break; } model = ui->comboBoxRpm->model(); @@ -155,7 +152,7 @@ NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) : Models::AddEntry(model, tr(rpmModes[i].toUtf8().data()), i); } - connect(ui->fileField, &FileField::fileSelected, this, [this](const QString& filename) { + connect(ui->fileField, &FileField::fileSelected, this, [this](const QString &filename) { bool hide = true; if (mediaType_ == MediaType::Floppy) { if (QFileInfo(filename).suffix().toLower() == QStringLiteral("86f")) { @@ -172,134 +169,140 @@ NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) : ui->comboBoxRpm->setHidden(true); } -NewFloppyDialog::~NewFloppyDialog() { +NewFloppyDialog::~NewFloppyDialog() +{ delete ui; } -QString NewFloppyDialog::fileName() const{ +QString +NewFloppyDialog::fileName() const +{ return ui->fileField->fileName(); } -void NewFloppyDialog::onCreate() { - auto filename = ui->fileField->fileName(); +void +NewFloppyDialog::onCreate() +{ + auto filename = ui->fileField->fileName(); QFileInfo fi(filename); - FileType fileType; + FileType fileType; QProgressDialog progress("Creating floppy image", QString(), 0, 100, this); connect(this, &NewFloppyDialog::fileProgress, &progress, &QProgressDialog::setValue); connect(this, &NewFloppyDialog::fileProgress, [] { QApplication::processEvents(); }); switch (mediaType_) { - case MediaType::Floppy: - if (fi.suffix().toLower() == QStringLiteral("86f")) { - if (create86f(filename, disk_sizes[ui->comboBoxSize->currentIndex()], ui->comboBoxRpm->currentIndex())) { - return; + case MediaType::Floppy: + if (fi.suffix().toLower() == QStringLiteral("86f")) { + if (create86f(filename, disk_sizes[ui->comboBoxSize->currentIndex()], ui->comboBoxRpm->currentIndex())) { + return; + } + } else { + fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Fdi : FileType::Img; + if (createSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex()], fileType)) { + return; + } } - } else { - fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Fdi : FileType::Img; - if (createSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex()], fileType)) { - return; + break; + case MediaType::Zip: + { + fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Zdi : FileType::Img; + + std::atomic_bool res; + std::thread t([this, &res, filename, fileType, &progress] { + res = createZipSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex() + 12], fileType, progress); + }); + progress.exec(); + t.join(); + + if (res) { + return; + } } - } - break; - case MediaType::Zip: - { - fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Zdi: FileType::Img; + break; + case MediaType::Mo: + { + fileType = fi.suffix().toLower() == QStringLiteral("mdi") ? FileType::Mdi : FileType::Img; - std::atomic_bool res; - std::thread t([this, &res, filename, fileType, &progress] { - res = createZipSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex() + 12], fileType, progress); - }); - progress.exec(); - t.join(); + std::atomic_bool res; + std::thread t([this, &res, filename, fileType, &progress] { + res = createMoSectorImage(filename, ui->comboBoxSize->currentIndex(), fileType, progress); + }); + progress.exec(); + t.join(); - if (res) { - return; - } - } - break; - case MediaType::Mo: - { - fileType = fi.suffix().toLower() == QStringLiteral("mdi") ? FileType::Mdi: FileType::Img; - - std::atomic_bool res; - std::thread t([this, &res, filename, fileType, &progress] { - res = createMoSectorImage(filename, ui->comboBoxSize->currentIndex(), fileType, progress); - }); - progress.exec(); - t.join(); - - if (res) { - return; - } - } - break; + if (res) { + return; + } + } + break; } QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory")); reject(); } -bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk_size, uint8_t rpm_mode) +bool +NewFloppyDialog::create86f(const QString &filename, const disk_size_t &disk_size, uint8_t rpm_mode) { FILE *f; - uint32_t magic = 0x46423638; - uint16_t version = 0x020C; - uint16_t dflags = 0; - uint16_t tflags = 0; + uint32_t magic = 0x46423638; + uint16_t version = 0x020C; + uint16_t dflags = 0; + uint16_t tflags = 0; uint32_t index_hole_pos = 0; uint32_t tarray[512]; uint32_t array_size; uint32_t track_base, track_size; - int i; + int i; uint32_t shift = 0; - dflags = 0; /* Has surface data? - Assume no for now. */ - dflags |= (disk_size.hole << 1); /* Hole */ - dflags |= ((disk_size.sides - 1) << 3); /* Sides. */ - dflags |= (0 << 4); /* Write protect? - Assume no for now. */ - dflags |= (rpm_mode << 5); /* RPM mode. */ - dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */ + dflags = 0; /* Has surface data? - Assume no for now. */ + dflags |= (disk_size.hole << 1); /* Hole */ + dflags |= ((disk_size.sides - 1) << 3); /* Sides. */ + dflags |= (0 << 4); /* Write protect? - Assume no for now. */ + dflags |= (rpm_mode << 5); /* RPM mode. */ + dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */ - tflags = disk_size.data_rate; /* Data rate. */ - tflags |= (disk_size.encoding << 3); /* Encoding. */ - tflags |= (disk_size.rpm << 5); /* RPM. */ + tflags = disk_size.data_rate; /* Data rate. */ + tflags |= (disk_size.encoding << 3); /* Encoding. */ + tflags |= (disk_size.rpm << 5); /* RPM. */ switch (disk_size.hole) { - case 0: - case 1: - default: - switch(rpm_mode) { - case 1: - array_size = 25250; - break; - case 2: - array_size = 25374; - break; - case 3: - array_size = 25750; - break; - default: - array_size = 25000; - break; - } - break; - case 2: - switch(rpm_mode) { - case 1: - array_size = 50500; - break; - case 2: - array_size = 50750; - break; - case 3: - array_size = 51000; - break; - default: - array_size = 50000; - break; - } - break; + case 0: + case 1: + default: + switch (rpm_mode) { + case 1: + array_size = 25250; + break; + case 2: + array_size = 25374; + break; + case 3: + array_size = 25750; + break; + default: + array_size = 25000; + break; + } + break; + case 2: + switch (rpm_mode) { + case 1: + array_size = 50500; + break; + case 2: + array_size = 50750; + break; + case 3: + array_size = 51000; + break; + default: + array_size = 50000; + break; + } + break; } auto empty = (unsigned char *) malloc(array_size); @@ -309,7 +312,7 @@ bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk f = plat_fopen(filename.toUtf8().data(), "wb"); if (!f) - return false; + return false; fwrite(&magic, 4, 1, f); fwrite(&version, 2, 1, f); @@ -320,17 +323,17 @@ bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk track_base = 8 + ((disk_size.sides == 2) ? 2048 : 1024); if (disk_size.tracks <= 43) - shift = 1; + shift = 1; for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) - tarray[i] = track_base + (i * track_size); + tarray[i] = track_base + (i * track_size); fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, f); for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) { - fwrite(&tflags, 2, 1, f); - fwrite(&index_hole_pos, 4, 1, f); - fwrite(empty, 1, array_size, f); + fwrite(&tflags, 2, 1, f); + fwrite(&index_hole_pos, 4, 1, f); + fwrite(empty, 1, array_size, f); } free(empty); @@ -342,61 +345,62 @@ bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk /* Ignore false positive warning caused by a bug on gcc */ #if __GNUC__ >= 11 -#pragma GCC diagnostic ignored "-Wstringop-overflow" +# pragma GCC diagnostic ignored "-Wstringop-overflow" #endif -bool NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type) +bool +NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type) { - uint32_t total_size = 0; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; + uint32_t total_size = 0; + uint32_t total_sectors = 0; + uint32_t sector_bytes = 0; uint32_t root_dir_bytes = 0; - uint32_t fat_size = 0; - uint32_t fat1_offs = 0; - uint32_t fat2_offs = 0; - uint32_t zero_bytes = 0; - uint16_t base = 0x1000; + uint32_t fat_size = 0; + uint32_t fat1_offs = 0; + uint32_t fat2_offs = 0; + uint32_t zero_bytes = 0; + uint16_t base = 0x1000; QFile file(filename); - if (! file.open(QIODevice::WriteOnly)) { + if (!file.open(QIODevice::WriteOnly)) { return false; } QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); - sector_bytes = (128 << disk_size.sector_len); + sector_bytes = (128 << disk_size.sector_len); total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; if (total_sectors > ZIP_SECTORS) total_sectors = ZIP_250_SECTORS; - total_size = total_sectors * sector_bytes; + total_size = total_sectors * sector_bytes; root_dir_bytes = (disk_size.root_dir_entries << 5); - fat_size = (disk_size.spfat * sector_bytes); - fat1_offs = sector_bytes; - fat2_offs = fat1_offs + fat_size; - zero_bytes = fat2_offs + fat_size + root_dir_bytes; + fat_size = (disk_size.spfat * sector_bytes); + fat1_offs = sector_bytes; + fat2_offs = fat1_offs + fat_size; + zero_bytes = fat2_offs + fat_size + root_dir_bytes; if (type == FileType::Fdi) { QByteArray bytes(base, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); *(uint32_t *) &(empty[0x08]) = (uint32_t) base; *(uint32_t *) &(empty[0x0C]) = total_size; *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; + *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; + *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; stream.writeRawData(empty, base); } QByteArray bytes(total_size, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); memset(empty + zero_bytes, 0xF6, total_size - zero_bytes); - empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */ + empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */ empty[0x01] = 0x58; empty[0x02] = 0x90; - empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */ + empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */ empty[0x04] = 0x36; empty[0x05] = 0x42; empty[0x06] = 0x4F; @@ -406,17 +410,17 @@ bool NewFloppyDialog::createSectorImage(const QString &filename, const disk_size empty[0x0A] = 0x30; *(uint16_t *) &(empty[0x0B]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc; + *(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc; *(uint16_t *) &(empty[0x0E]) = (uint16_t) 1; - *(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats; + *(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats; *(uint16_t *) &(empty[0x11]) = (uint16_t) disk_size.root_dir_entries; *(uint16_t *) &(empty[0x13]) = (uint16_t) total_sectors; - *(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc; + *(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc; *(uint16_t *) &(empty[0x16]) = (uint16_t) disk_size.spfat; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides; - empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */ empty[0x27] = random_generate(); empty[0x28] = random_generate(); empty[0x29] = random_generate(); @@ -442,22 +446,23 @@ bool NewFloppyDialog::createSectorImage(const QString &filename, const disk_size return true; } -bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type, QProgressDialog& pbar) +bool +NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar) { - uint32_t total_size = 0; + uint32_t total_size = 0; uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint16_t base = 0x1000; - uint32_t pbar_max = 0; + uint32_t sector_bytes = 0; + uint16_t base = 0x1000; + uint32_t pbar_max = 0; QFile file(filename); - if (! file.open(QIODevice::WriteOnly)) { + if (!file.open(QIODevice::WriteOnly)) { return false; } QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); - sector_bytes = (128 << disk_size.sector_len); + sector_bytes = (128 << disk_size.sector_len); total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; if (total_sectors > ZIP_SECTORS) total_sectors = ZIP_250_SECTORS; @@ -471,21 +476,21 @@ bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_s if (type == FileType::Zdi) { QByteArray data(base, 0); - auto empty = data.data(); + auto empty = data.data(); *(uint32_t *) &(empty[0x08]) = (uint32_t) base; *(uint32_t *) &(empty[0x0C]) = total_size; *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; + *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; + *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; stream.writeRawData(empty, base); pbar_max -= 2; } QByteArray bytes(total_size, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); if (total_sectors == ZIP_SECTORS) { /* ZIP 100 */ @@ -515,7 +520,7 @@ bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_s *(uint32_t *) &(empty[0x4020]) = 0x0002FFE0; *(uint16_t *) &(empty[0x4024]) = 0x0080; - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ empty[0x4027] = random_generate(); empty[0x4028] = random_generate(); empty[0x4029] = random_generate(); @@ -586,7 +591,7 @@ bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_s *(uint32_t *) &(empty[0x4020]) = 0x000777E0; *(uint16_t *) &(empty[0x4024]) = 0x0080; - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ empty[0x4027] = random_generate(); empty[0x4028] = random_generate(); empty[0x4029] = random_generate(); @@ -624,26 +629,26 @@ bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_s return true; } - -bool NewFloppyDialog::createMoSectorImage(const QString& filename, int8_t disk_size, FileType type, QProgressDialog& pbar) +bool +NewFloppyDialog::createMoSectorImage(const QString &filename, int8_t disk_size, FileType type, QProgressDialog &pbar) { - const mo_type_t *dp = &mo_types[disk_size]; - uint32_t total_size = 0, total_size2; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint16_t base = 0x1000; - uint32_t pbar_max = 0, blocks_num; + const mo_type_t *dp = &mo_types[disk_size]; + uint32_t total_size = 0, total_size2; + uint32_t total_sectors = 0; + uint32_t sector_bytes = 0; + uint16_t base = 0x1000; + uint32_t pbar_max = 0, blocks_num; QFile file(filename); - if (! file.open(QIODevice::WriteOnly)) { + if (!file.open(QIODevice::WriteOnly)) { return false; } QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); - sector_bytes = dp->bytes_per_sector; + sector_bytes = dp->bytes_per_sector; total_sectors = dp->sectors; - total_size = total_sectors * sector_bytes; + total_size = total_sectors * sector_bytes; total_size2 = (total_size >> 20) << 20; total_size2 = total_size - total_size2; @@ -658,20 +663,20 @@ bool NewFloppyDialog::createMoSectorImage(const QString& filename, int8_t disk_s if (type == FileType::Mdi) { QByteArray bytes(base, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); *(uint32_t *) &(empty[0x08]) = (uint32_t) base; *(uint32_t *) &(empty[0x0C]) = total_size; *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) 25; - *(uint8_t *) &(empty[0x18]) = (uint8_t) 64; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) (dp->sectors / 64) / 25; + *(uint8_t *) &(empty[0x14]) = (uint8_t) 25; + *(uint8_t *) &(empty[0x18]) = (uint8_t) 64; + *(uint8_t *) &(empty[0x1C]) = (uint8_t) (dp->sectors / 64) / 25; stream.writeRawData(empty, base); } QByteArray bytes(1048576, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); pbar.setMaximum(blocks_num); for (uint32_t i = 0; i < blocks_num; i++) { diff --git a/src/qt/qt_newfloppydialog.hpp b/src/qt/qt_newfloppydialog.hpp index 12e761cdf..a342df567 100644 --- a/src/qt/qt_newfloppydialog.hpp +++ b/src/qt/qt_newfloppydialog.hpp @@ -10,8 +10,7 @@ class NewFloppyDialog; struct disk_size_t; class QProgressDialog; -class NewFloppyDialog : public QDialog -{ +class NewFloppyDialog : public QDialog { Q_OBJECT public: @@ -39,12 +38,12 @@ private slots: private: Ui::NewFloppyDialog *ui; - MediaType mediaType_; + MediaType mediaType_; - bool create86f(const QString& filename, const disk_size_t& disk_size, uint8_t rpm_mode); - bool createSectorImage(const QString& filename, const disk_size_t& disk_size, FileType type); - bool createZipSectorImage(const QString& filename, const disk_size_t& disk_size, FileType type, QProgressDialog& pbar); - bool createMoSectorImage(const QString& filename, int8_t disk_size, FileType type, QProgressDialog& pbar); + bool create86f(const QString &filename, const disk_size_t &disk_size, uint8_t rpm_mode); + bool createSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type); + bool createZipSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar); + bool createMoSectorImage(const QString &filename, int8_t disk_size, FileType type, QProgressDialog &pbar); }; #endif // QT_NEWFLOPPYDIALOG_HPP diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 6d5b36d80..a2f1ecad0 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -27,11 +27,11 @@ #include "qt_openglrenderer.hpp" #ifndef GL_MAP_PERSISTENT_BIT -#define GL_MAP_PERSISTENT_BIT 0x0040 +# define GL_MAP_PERSISTENT_BIT 0x0040 #endif #ifndef GL_MAP_COHERENT_BIT -#define GL_MAP_COHERENT_BIT 0x0080 +# define GL_MAP_COHERENT_BIT 0x0080 #endif OpenGLRenderer::OpenGLRenderer(QWidget *parent) @@ -321,7 +321,10 @@ OpenGLRenderer::applyOptions() void OpenGLRenderer::reloadOptions() { - if (options) { delete options; options = nullptr; } + if (options) { + delete options; + options = nullptr; + } options = new OpenGLOptions(this, true, glslVersion); applyOptions(); diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index 99393c30d..c303ca614 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -39,7 +39,7 @@ #include "qt_opengloptions.hpp" #include "qt_renderercommon.hpp" -typedef void (QOPENGLF_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC_LOCAL) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void(QOPENGLF_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC_LOCAL)(GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); class OpenGLRenderer : public QWindow, protected QOpenGLExtraFunctions, public RendererCommon { Q_OBJECT diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 734af2aab..0fe611cbe 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -44,23 +44,28 @@ #include "qt_progsettings.hpp" #ifdef Q_OS_UNIX -#include +# include #endif // static QByteArray buf; extern QElapsedTimer elapsed_timer; -extern MainWindow* main_window; -QElapsedTimer elapsed_timer; +extern MainWindow *main_window; +QElapsedTimer elapsed_timer; -static std::atomic_int blitmx_contention = 0; +static std::atomic_int blitmx_contention = 0; static std::recursive_mutex blitmx; class CharPointer { public: - CharPointer(char* buf, int size) : b(buf), s(size) {} - CharPointer& operator=(const QByteArray &ba) { + CharPointer(char *buf, int size) + : b(buf) + , s(size) + { + } + CharPointer &operator=(const QByteArray &ba) + { if (s > 0) { - strncpy(b, ba.data(), s-1); + strncpy(b, ba.data(), s - 1); b[s] = 0; } else { // if we haven't been told the length of b, just assume enough @@ -70,9 +75,10 @@ public: } return *this; } + private: - char* b; - int s; + char *b; + int s; }; extern "C" { @@ -101,18 +107,19 @@ extern "C" { #include "../cpu/cpu.h" #include <86box/plat.h> -volatile int cpu_thread_run = 1; -int mouse_capture = 0; -int fixed_size_x = 640; -int fixed_size_y = 480; -int rctrl_is_lalt = 0; -int update_icons = 1; -int kbd_req_capture = 0; -int hide_status_bar = 0; -int hide_tool_bar = 0; -uint32_t lang_id = 0x0409, lang_sys = 0x0409; // Multilangual UI variables, for now all set to LCID of en-US +volatile int cpu_thread_run = 1; +int mouse_capture = 0; +int fixed_size_x = 640; +int fixed_size_y = 480; +int rctrl_is_lalt = 0; +int update_icons = 1; +int kbd_req_capture = 0; +int hide_status_bar = 0; +int hide_tool_bar = 0; +uint32_t lang_id = 0x0409, lang_sys = 0x0409; // Multilangual UI variables, for now all set to LCID of en-US -int stricmp(const char* s1, const char* s2) +int +stricmp(const char *s1, const char *s2) { #ifdef Q_OS_WINDOWS return _stricmp(s1, s2); @@ -121,7 +128,8 @@ int stricmp(const char* s1, const char* s2) #endif } -int strnicmp(const char *s1, const char *s2, size_t n) +int +strnicmp(const char *s1, const char *s2, size_t n) { #ifdef Q_OS_WINDOWS return _strnicmp(s1, s2, n); @@ -134,14 +142,15 @@ void do_stop(void) { cpu_thread_run = 0; - //main_window->close(); + // main_window->close(); } -void plat_get_exe_name(char *s, int size) +void +plat_get_exe_name(char *s, int size) { QByteArray exepath_temp = QCoreApplication::applicationDirPath().toLocal8Bit(); - memcpy(s, exepath_temp.data(), std::min((qsizetype)exepath_temp.size(),(qsizetype)size)); + memcpy(s, exepath_temp.data(), std::min((qsizetype) exepath_temp.size(), (qsizetype) size)); path_slash(s); } @@ -163,7 +172,7 @@ plat_fopen(const char *path, const char *mode) { #if defined(Q_OS_MACOS) or defined(Q_OS_LINUX) QFileInfo fi(path); - QString filename = (fi.isRelative() && !fi.filePath().isEmpty()) ? usr_path + fi.filePath() : fi.filePath(); + QString filename = (fi.isRelative() && !fi.filePath().isEmpty()) ? usr_path + fi.filePath() : fi.filePath(); return fopen(filename.toUtf8().constData(), mode); #else return fopen(QString::fromUtf8(path).toLocal8Bit(), mode); @@ -175,7 +184,7 @@ plat_fopen64(const char *path, const char *mode) { #if defined(Q_OS_MACOS) or defined(Q_OS_LINUX) QFileInfo fi(path); - QString filename = (fi.isRelative() && !fi.filePath().isEmpty()) ? usr_path + fi.filePath() : fi.filePath(); + QString filename = (fi.isRelative() && !fi.filePath().isEmpty()) ? usr_path + fi.filePath() : fi.filePath(); return fopen(filename.toUtf8().constData(), mode); #else return fopen(QString::fromUtf8(path).toLocal8Bit(), mode); @@ -220,9 +229,9 @@ path_get_extension(char *s) auto len = strlen(s); auto idx = QByteArray::fromRawData(s, len).lastIndexOf('.'); if (idx >= 0) { - return s+idx+1; + return s + idx + 1; } - return s+len; + return s + len; } char * @@ -232,16 +241,16 @@ path_get_filename(char *s) int c = strlen(s) - 1; while (c > 0) { - if (s[c] == '/' || s[c] == '\\') - return(&s[c+1]); - c--; + if (s[c] == '/' || s[c] == '\\') + return (&s[c + 1]); + c--; } - return(s); + return (s); #else - auto idx = QByteArray::fromRawData(s, strlen(s)).lastIndexOf(QDir::separator().toLatin1()); + auto idx = QByteArray::fromRawData(s, strlen(s)).lastIndexOf(QDir::separator().toLatin1()); if (idx >= 0) { - return s+idx+1; + return s + idx + 1; } return s; #endif @@ -261,12 +270,12 @@ path_abs(char *path) } void -path_normalize(char* path) +path_normalize(char *path) { #ifdef Q_OS_WINDOWS - while (*path++ != 0) - { - if (*path == '\\') *path = '/'; + while (*path++ != 0) { + if (*path == '\\') + *path = '/'; } #endif } @@ -274,11 +283,11 @@ path_normalize(char* path) void path_slash(char *path) { - auto len = strlen(path); + auto len = strlen(path); auto separator = '/'; - if (path[len-1] != separator) { - path[len] = separator; - path[len+1] = 0; + if (path[len - 1] != separator) { + path[len] = separator; + path[len + 1] = 0; } path_normalize(path); } @@ -300,12 +309,14 @@ plat_tempfile(char *bufp, char *prefix, char *suffix) name.append(QString("%1-").arg(prefix)); } - name.append(QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss-zzzz")); - if (suffix) name.append(suffix); - strcpy(bufp, name.toUtf8().data()); + name.append(QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss-zzzz")); + if (suffix) + name.append(suffix); + strcpy(bufp, name.toUtf8().data()); } -void plat_remove(char* path) +void +plat_remove(char *path) { QFile(path).remove(); } @@ -316,11 +327,11 @@ plat_mmap(size_t size, uint8_t executable) #if defined Q_OS_WINDOWS return VirtualAlloc(NULL, size, MEM_COMMIT, executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); #elif defined Q_OS_UNIX -#if defined Q_OS_DARWIN && defined MAP_JIT +# if defined Q_OS_DARWIN && defined MAP_JIT void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE | (executable ? MAP_JIT : 0), -1, 0); -#else +# else void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, -1, 0); -#endif +# endif return (ret == MAP_FAILED) ? nullptr : ret; #endif } @@ -339,12 +350,12 @@ void plat_pause(int p) { static wchar_t oldtitle[512]; - wchar_t title[1024], paused_msg[512]; + wchar_t title[1024], paused_msg[512]; if (p == dopause) { #ifdef Q_OS_WINDOWS if (source_hwnd) - PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDSTATUS, (WPARAM)!!p, (LPARAM)(HWND)main_window->winId()); + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!p, (LPARAM) (HWND) main_window->winId()); #endif return; } @@ -354,8 +365,8 @@ plat_pause(int p) dopause = p; if (p) { - if (mouse_capture) - plat_mouse_capture(0); + if (mouse_capture) + plat_mouse_capture(0); wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1); wcscpy(title, oldtitle); @@ -370,12 +381,12 @@ plat_pause(int p) #ifdef Q_OS_WINDOWS if (source_hwnd) - PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDSTATUS, (WPARAM)!!p, (LPARAM)(HWND)main_window->winId()); + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!p, (LPARAM) (HWND) main_window->winId()); #endif } // because we can't include nvr.h because it's got fields named new -extern int nvr_save(void); +extern int nvr_save(void); void plat_power_off(void) @@ -393,44 +404,45 @@ plat_power_off(void) QTimer::singleShot(0, (const QWidget *) main_window, &QMainWindow::close); } -void set_language(uint32_t id) { +void +set_language(uint32_t id) +{ lang_id = id; } -extern "C++" -{ - QMap> ProgSettings::lcid_langcode = - { - {0x0405, {"cs-CZ", "Czech (Czech Republic)"} }, - {0x0407, {"de-DE", "German (Germany)"} }, - {0x0409, {"en-US", "English (United States)"} }, - {0x0809, {"en-GB", "English (United Kingdom)"} }, - {0x0C0A, {"es-ES", "Spanish (Spain)"} }, - {0x040B, {"fi-FI", "Finnish (Finland)"} }, - {0x040C, {"fr-FR", "French (France)"} }, - {0x041A, {"hr-HR", "Croatian (Croatia)"} }, - {0x040E, {"hu-HU", "Hungarian (Hungary)"} }, - {0x0410, {"it-IT", "Italian (Italy)"} }, - {0x0411, {"ja-JP", "Japanese (Japan)"} }, - {0x0412, {"ko-KR", "Korean (Korea)"} }, - {0x0415, {"pl-PL", "Polish (Poland)"} }, - {0x0416, {"pt-BR", "Portuguese (Brazil)"} }, - {0x0816, {"pt-PT", "Portuguese (Portugal)"} }, - {0x0419, {"ru-RU", "Russian (Russia)"} }, - {0x0424, {"sl-SI", "Slovenian (Slovenia)"} }, - {0x041F, {"tr-TR", "Turkish (Turkey)"} }, - {0x0422, {"uk-UA", "Ukrainian (Ukraine)"} }, - {0x0804, {"zh-CN", "Chinese (China)"} }, - {0xFFFF, {"system", "(System Default)"} }, - }; +extern "C++" { +QMap> ProgSettings::lcid_langcode = { + {0x0405, { "cs-CZ", "Czech (Czech Republic)" } }, + { 0x0407, { "de-DE", "German (Germany)" } }, + { 0x0409, { "en-US", "English (United States)" } }, + { 0x0809, { "en-GB", "English (United Kingdom)" }}, + { 0x0C0A, { "es-ES", "Spanish (Spain)" } }, + { 0x040B, { "fi-FI", "Finnish (Finland)" } }, + { 0x040C, { "fr-FR", "French (France)" } }, + { 0x041A, { "hr-HR", "Croatian (Croatia)" } }, + { 0x040E, { "hu-HU", "Hungarian (Hungary)" } }, + { 0x0410, { "it-IT", "Italian (Italy)" } }, + { 0x0411, { "ja-JP", "Japanese (Japan)" } }, + { 0x0412, { "ko-KR", "Korean (Korea)" } }, + { 0x0415, { "pl-PL", "Polish (Poland)" } }, + { 0x0416, { "pt-BR", "Portuguese (Brazil)" } }, + { 0x0816, { "pt-PT", "Portuguese (Portugal)" } }, + { 0x0419, { "ru-RU", "Russian (Russia)" } }, + { 0x0424, { "sl-SI", "Slovenian (Slovenia)" } }, + { 0x041F, { "tr-TR", "Turkish (Turkey)" } }, + { 0x0422, { "uk-UA", "Ukrainian (Ukraine)" } }, + { 0x0804, { "zh-CN", "Chinese (China)" } }, + { 0x0404, { "zh-TW", "Chinese (Taiwan)" } }, + { 0xFFFF, { "system", "(System Default)" } }, +}; } /* Sets up the program language before initialization. */ -uint32_t plat_language_code(char* langcode) { - for (auto& curKey : ProgSettings::lcid_langcode.keys()) - { - if (ProgSettings::lcid_langcode[curKey].first == langcode) - { +uint32_t +plat_language_code(char *langcode) +{ + for (auto &curKey : ProgSettings::lcid_langcode.keys()) { + if (ProgSettings::lcid_langcode[curKey].first == langcode) { return curKey; } } @@ -438,9 +450,10 @@ uint32_t plat_language_code(char* langcode) { } /* Converts back the language code to LCID */ -void plat_language_code_r(uint32_t lcid, char* outbuf, int len) { - if (!ProgSettings::lcid_langcode.contains(lcid)) - { +void +plat_language_code_r(uint32_t lcid, char *outbuf, int len) +{ + if (!ProgSettings::lcid_langcode.contains(lcid)) { qstrncpy(outbuf, "system", len); return; } @@ -449,25 +462,25 @@ void plat_language_code_r(uint32_t lcid, char* outbuf, int len) { } #ifndef Q_OS_WINDOWS -void* dynld_module(const char *name, dllimp_t *table) +void * +dynld_module(const char *name, dllimp_t *table) { - QString libraryName = name; - QFileInfo fi(libraryName); - QStringList removeSuffixes = {"dll", "dylib", "so"}; + QString libraryName = name; + QFileInfo fi(libraryName); + QStringList removeSuffixes = { "dll", "dylib", "so" }; if (removeSuffixes.contains(fi.suffix())) { libraryName = fi.completeBaseName(); } auto lib = std::unique_ptr(new QLibrary(libraryName)); if (lib->load()) { - for (auto imp = table; imp->name != nullptr; imp++) - { + for (auto imp = table; imp->name != nullptr; imp++) { auto ptr = lib->resolve(imp->name); if (ptr == nullptr) { return nullptr; } - auto imp_ptr = reinterpret_cast(imp->func); - *imp_ptr = reinterpret_cast(ptr); + auto imp_ptr = reinterpret_cast(imp->func); + *imp_ptr = reinterpret_cast(ptr); } } else { return nullptr; @@ -476,13 +489,15 @@ void* dynld_module(const char *name, dllimp_t *table) return lib.release(); } -void dynld_close(void *handle) +void +dynld_close(void *handle) { - delete reinterpret_cast(handle); + delete reinterpret_cast(handle); } #endif -void startblit() +void +startblit() { blitmx_contention++; if (blitmx.try_lock()) { @@ -492,7 +507,8 @@ void startblit() blitmx.lock(); } -void endblit() +void +endblit() { blitmx_contention--; blitmx.unlock(); @@ -503,33 +519,38 @@ void endblit() std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } - } #ifdef Q_OS_WINDOWS -size_t mbstoc16s(uint16_t dst[], const char src[], int len) +size_t +mbstoc16s(uint16_t dst[], const char src[], int len) { - if (src == NULL) return 0; - if (len < 0) return 0; + if (src == NULL) + return 0; + if (len < 0) + return 0; size_t ret = MultiByteToWideChar(CP_UTF8, 0, src, -1, reinterpret_cast(dst), dst == NULL ? 0 : len); if (!ret) { - return -1; + return -1; } return ret; } -size_t c16stombs(char dst[], const uint16_t src[], int len) +size_t +c16stombs(char dst[], const uint16_t src[], int len) { - if (src == NULL) return 0; - if (len < 0) return 0; + if (src == NULL) + return 0; + if (len < 0) + return 0; size_t ret = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast(src), -1, dst, dst == NULL ? 0 : len, NULL, NULL); if (!ret) { - return -1; + return -1; } return ret; @@ -537,69 +558,68 @@ size_t c16stombs(char dst[], const uint16_t src[], int len) #endif #ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#define LIB_NAME_GS "gsdll32.dll" -#define LIB_NAME_FREETYPE "freetype.dll" -#define MOUSE_CAPTURE_KEYSEQ "F8+F12" +# define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" +# define LIB_NAME_GS "gsdll32.dll" +# define LIB_NAME_FREETYPE "freetype.dll" +# define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#define LIB_NAME_GS "libgs" -#define LIB_NAME_FREETYPE "libfreetype" -#define MOUSE_CAPTURE_KEYSEQ "CTRL-END" +# define LIB_NAME_FLUIDSYNTH "libfluidsynth" +# define LIB_NAME_GS "libgs" +# define LIB_NAME_FREETYPE "libfreetype" +# define MOUSE_CAPTURE_KEYSEQ "CTRL-END" #endif - QMap ProgSettings::translatedstrings; -void ProgSettings::reloadStrings() +void +ProgSettings::reloadStrings() { translatedstrings.clear(); translatedstrings[IDS_2077] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); translatedstrings[IDS_2078] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); translatedstrings[IDS_2079] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); translatedstrings[IDS_2080] = QCoreApplication::translate("", "Failed to initialize FluidSynth").toStdWString(); - translatedstrings[IDS_2130] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); + translatedstrings[IDS_2131] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); translatedstrings[IDS_4099] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); - translatedstrings[IDS_2093] = QCoreApplication::translate("", "Failed to set up PCap").toStdWString(); - translatedstrings[IDS_2094] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); - translatedstrings[IDS_2095] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); - translatedstrings[IDS_2110] = QCoreApplication::translate("", "Unable to initialize FreeType").toStdWString(); - translatedstrings[IDS_2111] = QCoreApplication::translate("", "Unable to initialize SDL, libsdl2 is required").toStdWString(); - translatedstrings[IDS_2129] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); - translatedstrings[IDS_2114] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); + translatedstrings[IDS_2094] = QCoreApplication::translate("", "Failed to set up PCap").toStdWString(); + translatedstrings[IDS_2095] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); + translatedstrings[IDS_2096] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); + translatedstrings[IDS_2111] = QCoreApplication::translate("", "Unable to initialize FreeType").toStdWString(); + translatedstrings[IDS_2112] = QCoreApplication::translate("", "Unable to initialize SDL, libsdl2 is required").toStdWString(); + translatedstrings[IDS_2130] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); + translatedstrings[IDS_2115] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); translatedstrings[IDS_2063] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); translatedstrings[IDS_2064] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); - translatedstrings[IDS_2128] = QCoreApplication::translate("", "Hardware not available").toStdWString(); - translatedstrings[IDS_2142] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString(); - translatedstrings[IDS_2120] = QCoreApplication::translate("", "No ROMs found").toStdWString(); + translatedstrings[IDS_2129] = QCoreApplication::translate("", "Hardware not available").toStdWString(); + translatedstrings[IDS_2143] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString(); + translatedstrings[IDS_2121] = QCoreApplication::translate("", "No ROMs found").toStdWString(); translatedstrings[IDS_2056] = QCoreApplication::translate("", "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory.").toStdWString(); auto flsynthstr = QCoreApplication::translate("", " is required for FluidSynth MIDI output."); - if (flsynthstr.contains("libfluidsynth")) - { + if (flsynthstr.contains("libfluidsynth")) { flsynthstr.replace("libfluidsynth", LIB_NAME_FLUIDSYNTH); - } - else flsynthstr.prepend(LIB_NAME_FLUIDSYNTH); - translatedstrings[IDS_2133] = flsynthstr.toStdWString(); - auto gssynthstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); - if (gssynthstr.contains("libgs")) - { + } else + flsynthstr.prepend(LIB_NAME_FLUIDSYNTH); + translatedstrings[IDS_2134] = flsynthstr.toStdWString(); + auto gssynthstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); + if (gssynthstr.contains("libgs")) { gssynthstr.replace("libgs", LIB_NAME_GS); - } - else gssynthstr.prepend(LIB_NAME_GS); - translatedstrings[IDS_2132] = gssynthstr.toStdWString(); - auto ftsynthstr = QCoreApplication::translate("", " is required for ESC/P printer emulation."); - if (ftsynthstr.contains("libfreetype")) - { + } else + gssynthstr.prepend(LIB_NAME_GS); + translatedstrings[IDS_2133] = gssynthstr.toStdWString(); + auto ftsynthstr = QCoreApplication::translate("", " is required for ESC/P printer emulation."); + if (ftsynthstr.contains("libfreetype")) { ftsynthstr.replace("libfreetype", LIB_NAME_FREETYPE); - } - else ftsynthstr.prepend(LIB_NAME_FREETYPE); - translatedstrings[IDS_2131] = ftsynthstr.toStdWString(); + } else + ftsynthstr.prepend(LIB_NAME_FREETYPE); + translatedstrings[IDS_2132] = ftsynthstr.toStdWString(); } -wchar_t* plat_get_string(int i) +wchar_t * +plat_get_string(int i) { - if (ProgSettings::translatedstrings.empty()) ProgSettings::reloadStrings(); + if (ProgSettings::translatedstrings.empty()) + ProgSettings::reloadStrings(); return ProgSettings::translatedstrings[i].data(); } @@ -635,7 +655,7 @@ plat_init_rom_paths() paths.removeLast(); #endif - for (auto& path : paths) { + for (auto &path : paths) { #ifdef __APPLE__ rom_add_path(QDir(path).filePath("net.86Box.86Box/roms").toUtf8().constData()); #else diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 6018b0158..3ee998002 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -27,8 +27,7 @@ #include #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/version.h> #include <86box/config.h> @@ -37,13 +36,13 @@ extern "C" #include <86box/rom.h> } - static QMap iconset_to_qt; -extern MainWindow* main_window; +extern MainWindow *main_window; -ProgSettings::CustomTranslator* ProgSettings::translator = nullptr; -QTranslator* ProgSettings::qtTranslator = nullptr; -QString ProgSettings::getIconSetPath() +ProgSettings::CustomTranslator *ProgSettings::translator = nullptr; +QTranslator *ProgSettings::qtTranslator = nullptr; +QString +ProgSettings::getIconSetPath() { if (iconset_to_qt.isEmpty()) { // Always include default bundled icons @@ -66,46 +65,48 @@ QString ProgSettings::getIconSetPath() return iconset_to_qt[icon_set]; } -QIcon ProgSettings::loadIcon(QString file) +QIcon +ProgSettings::loadIcon(QString file) { - (void)getIconSetPath(); - if (!QFile::exists(iconset_to_qt[icon_set] + file)) return QIcon(iconset_to_qt[""] + file); + (void) getIconSetPath(); + if (!QFile::exists(iconset_to_qt[icon_set] + file)) + return QIcon(iconset_to_qt[""] + file); return QIcon(iconset_to_qt[icon_set] + file); } -ProgSettings::ProgSettings(QWidget *parent) : - QDialog(parent), - ui(new Ui::ProgSettings) +ProgSettings::ProgSettings(QWidget *parent) + : QDialog(parent) + , ui(new Ui::ProgSettings) { ui->setupUi(this); - (void)getIconSetPath(); + (void) getIconSetPath(); ui->comboBox->setItemData(0, ""); ui->comboBox->setCurrentIndex(0); - for (auto i = iconset_to_qt.begin(); i != iconset_to_qt.end(); i++) - { - if (i.key() == "") continue; + for (auto i = iconset_to_qt.begin(); i != iconset_to_qt.end(); i++) { + if (i.key() == "") + continue; QFile iconfile(i.value() + "/iconinfo.txt"); iconfile.open(QFile::ReadOnly); QString friendlyName; QString iconsetinfo(iconfile.readAll()); iconfile.close(); - if (iconsetinfo.isEmpty()) friendlyName = i.key(); - else friendlyName = iconsetinfo.split('\n')[0]; + if (iconsetinfo.isEmpty()) + friendlyName = i.key(); + else + friendlyName = iconsetinfo.split('\n')[0]; ui->comboBox->addItem(friendlyName, i.key()); - if (strcmp(icon_set, i.key().toUtf8().data()) == 0) - { + if (strcmp(icon_set, i.key().toUtf8().data()) == 0) { ui->comboBox->setCurrentIndex(ui->comboBox->findData(i.key())); } } ui->comboBox->setItemData(0, '(' + tr("Default") + ')', Qt::DisplayRole); ui->comboBoxLanguage->setItemData(0, 0xFFFF); - for (auto i = lcid_langcode.begin(); i != lcid_langcode.end(); i++) - { - if (i.key() == 0xFFFF) continue; + for (auto i = lcid_langcode.begin(); i != lcid_langcode.end(); i++) { + if (i.key() == 0xFFFF) + continue; ui->comboBoxLanguage->addItem(lcid_langcode[i.key()].second, i.key()); - if (i.key() == lang_id) - { + if (i.key() == lang_id) { ui->comboBoxLanguage->setCurrentIndex(ui->comboBoxLanguage->findData(i.key())); } } @@ -115,10 +116,11 @@ ProgSettings::ProgSettings(QWidget *parent) : ui->openDirUsrPath->setChecked(open_dir_usr_path > 0); } -void ProgSettings::accept() +void +ProgSettings::accept() { strcpy(icon_set, ui->comboBox->currentData().toString().toUtf8().data()); - lang_id = ui->comboBoxLanguage->currentData().toUInt(); + lang_id = ui->comboBoxLanguage->currentData().toUInt(); open_dir_usr_path = ui->openDirUsrPath->isChecked() ? 1 : 0; loadTranslators(QCoreApplication::instance()); @@ -126,7 +128,8 @@ void ProgSettings::accept() update_mouse_msg(); main_window->ui->retranslateUi(main_window); QString vmname(vm_name); - if (vmname.at(vmname.size() - 1) == '"' || vmname.at(vmname.size() - 1) == '\'') vmname.truncate(vmname.size() - 1); + if (vmname.at(vmname.size() - 1) == '"' || vmname.at(vmname.size() - 1) == '\'') + vmname.truncate(vmname.size() - 1); main_window->setWindowTitle(QString("%1 - %2 %3").arg(vmname, EMU_NAME, EMU_VERSION_FULL)); QString msg = main_window->status->getMessage(); main_window->status.reset(new MachineStatus(main_window)); @@ -143,47 +146,42 @@ ProgSettings::~ProgSettings() delete ui; } -void ProgSettings::on_pushButton_released() +void +ProgSettings::on_pushButton_released() { ui->comboBox->setCurrentIndex(0); } -void ProgSettings::loadTranslators(QObject *parent) +void +ProgSettings::loadTranslators(QObject *parent) { - if (qtTranslator) - { + if (qtTranslator) { QApplication::removeTranslator(qtTranslator); qtTranslator = nullptr; } - if (translator) - { + if (translator) { QApplication::removeTranslator(translator); translator = nullptr; } - qtTranslator = new QTranslator(parent); - translator = new CustomTranslator(parent); + qtTranslator = new QTranslator(parent); + translator = new CustomTranslator(parent); QString localetofilename = ""; - if (lang_id == 0xFFFF || lcid_langcode.contains(lang_id) == false) - { - for (int i = 0; i < QLocale::system().uiLanguages().size(); i++) - { + if (lang_id == 0xFFFF || lcid_langcode.contains(lang_id) == false) { + for (int i = 0; i < QLocale::system().uiLanguages().size(); i++) { localetofilename = QLocale::system().uiLanguages()[i]; - if (translator->load(QLatin1String("86box_") + localetofilename, QLatin1String(":/"))) - { + if (translator->load(QLatin1String("86box_") + localetofilename, QLatin1String(":/"))) { qDebug() << "Translations loaded.\n"; QCoreApplication::installTranslator(translator); if (!qtTranslator->load(QLatin1String("qtbase_") + localetofilename.replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) qtTranslator->load(QLatin1String("qt_") + localetofilename.replace('-', '_'), QApplication::applicationDirPath() + "/./translations/"); - if (QApplication::installTranslator(qtTranslator)) - { - qDebug() << "Qt translations loaded." << "\n"; + if (QApplication::installTranslator(qtTranslator)) { + qDebug() << "Qt translations loaded." + << "\n"; } break; } } - } - else - { + } else { translator->load(QLatin1String("86box_") + lcid_langcode[lang_id].first, QLatin1String(":/")); QCoreApplication::installTranslator(translator); if (!qtTranslator->load(QLatin1String("qtbase_") + QString(lcid_langcode[lang_id].first).replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) @@ -192,20 +190,21 @@ void ProgSettings::loadTranslators(QObject *parent) } } -void ProgSettings::on_pushButtonLanguage_released() +void +ProgSettings::on_pushButtonLanguage_released() { ui->comboBoxLanguage->setCurrentIndex(0); } -void ProgSettings::on_horizontalSlider_valueChanged(int value) +void +ProgSettings::on_horizontalSlider_valueChanged(int value) { - mouseSensitivity = (double)value / 100.; + mouseSensitivity = (double) value / 100.; } - -void ProgSettings::on_pushButton_2_clicked() +void +ProgSettings::on_pushButton_2_clicked() { mouseSensitivity = 1.0; ui->horizontalSlider->setValue(100); } - diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index 07cf62051..7565869b0 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -8,32 +8,36 @@ namespace Ui { class ProgSettings; } -class ProgSettings : public QDialog -{ +class ProgSettings : public QDialog { Q_OBJECT public: explicit ProgSettings(QWidget *parent = nullptr); ~ProgSettings(); static QString getIconSetPath(); - static QIcon loadIcon(QString file); - static void loadTranslators(QObject* parent = nullptr); - static void reloadStrings(); - class CustomTranslator : public QTranslator - { + static QIcon loadIcon(QString file); + static void loadTranslators(QObject *parent = nullptr); + static void reloadStrings(); + class CustomTranslator : public QTranslator { public: - CustomTranslator(QObject* parent = nullptr) : QTranslator(parent) {}; + CustomTranslator(QObject *parent = nullptr) + : QTranslator(parent) {}; + protected: QString translate(const char *context, const char *sourceText, - const char *disambiguation = nullptr, int n = -1) const override + const char *disambiguation = nullptr, int n = -1) const override { - if (strcmp(sourceText, "&Fullscreen") == 0) sourceText = "&Fullscreen\tCtrl+Alt+PgUp"; - if (strcmp(sourceText, "&Ctrl+Alt+Del") == 0) sourceText = "&Ctrl+Alt+Del\tCtrl+F12"; - if (strcmp(sourceText, "Take s&creenshot") == 0) sourceText = "Take s&creenshot\tCtrl+F11"; - if (strcmp(sourceText, "Begin trace") == 0) sourceText = "Begin trace\tCtrl+T"; - if (strcmp(sourceText, "End trace") == 0) sourceText = "End trace\tCtrl+T"; - if (strcmp(sourceText, "&Qt (Software)") == 0) - { + if (strcmp(sourceText, "&Fullscreen") == 0) + sourceText = "&Fullscreen\tCtrl+Alt+PgUp"; + if (strcmp(sourceText, "&Ctrl+Alt+Del") == 0) + sourceText = "&Ctrl+Alt+Del\tCtrl+F12"; + if (strcmp(sourceText, "Take s&creenshot") == 0) + sourceText = "Take s&creenshot\tCtrl+F11"; + if (strcmp(sourceText, "Begin trace") == 0) + sourceText = "Begin trace\tCtrl+T"; + if (strcmp(sourceText, "End trace") == 0) + sourceText = "End trace\tCtrl+T"; + if (strcmp(sourceText, "&Qt (Software)") == 0) { QString finalstr = QTranslator::translate("", "&SDL (Software)", disambiguation, n); finalstr.replace("SDL", "Qt"); finalstr.replace("(&S)", "(&Q)"); @@ -41,15 +45,16 @@ public: } QString finalstr = QTranslator::translate("", sourceText, disambiguation, n); #ifdef Q_OS_MACOS - if (finalstr.contains('\t')) finalstr.truncate(finalstr.indexOf('\t')); + if (finalstr.contains('\t')) + finalstr.truncate(finalstr.indexOf('\t')); #endif return finalstr; } }; - static CustomTranslator* translator; - static QTranslator* qtTranslator; + static CustomTranslator *translator; + static QTranslator *qtTranslator; static QMap> lcid_langcode; - static QMap translatedstrings; + static QMap translatedstrings; protected slots: void accept() override; diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 0b8108b00..98fb27ca0 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -32,79 +32,83 @@ extern "C" { RendererCommon::RendererCommon() = default; -extern MainWindow* main_window; +extern MainWindow *main_window; -static void integer_scale(double *d, double *g) { +static void +integer_scale(double *d, double *g) +{ double ratio; if (*d > *g) { ratio = std::floor(*d / *g); - *d = *g * ratio; + *d = *g * ratio; } else { ratio = std::ceil(*d / *g); - *d = *g / ratio; + *d = *g / ratio; } } -void RendererCommon::onResize(int width, int height) { +void +RendererCommon::onResize(int width, int height) +{ if ((video_fullscreen == 0) && (video_fullscreen_scale_maximized ? ((parentWidget->isMaximized() == false) && (main_window->isAncestorOf(parentWidget) && main_window->isMaximized() == false)) : 1)) { destination.setRect(0, 0, width, height); return; } double dx, dy, dw, dh, gsr; - double hw = width; - double hh = height; - double gw = source.width(); - double gh = source.height(); + double hw = width; + double hh = height; + double gw = source.width(); + double gh = source.height(); double hsr = hw / hh; switch (video_fullscreen_scale) { - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - integer_scale(&dw, &gw); - integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - destination.setRect(dx, dy, dw, dh); - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) { - gsr = 4.0 / 3.0; - } else { + case FULLSCR_SCALE_INT: gsr = gw / gh; - } + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + integer_scale(&dw, &gw); + integer_scale(&dh, &gh); + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect(dx, dy, dw, dh); + break; + case FULLSCR_SCALE_43: + case FULLSCR_SCALE_KEEPRATIO: + if (video_fullscreen_scale == FULLSCR_SCALE_43) { + gsr = 4.0 / 3.0; + } else { + gsr = gw / gh; + } - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - destination.setRect(dx, dy, dw, dh); - break; - case FULLSCR_SCALE_FULL: - default: - destination.setRect(0, 0, hw, hh); - break; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect(dx, dy, dw, dh); + break; + case FULLSCR_SCALE_FULL: + default: + destination.setRect(0, 0, hw, hh); + break; } } -bool RendererCommon::eventDelegate(QEvent *event, bool& result) +bool +RendererCommon::eventDelegate(QEvent *event, bool &result) { - switch (event->type()) - { + switch (event->type()) { default: return false; case QEvent::KeyPress: diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 4a1b18341..97370ea3f 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -22,22 +22,26 @@ public: virtual uint32_t getBytesPerRow() { return 2048 * 4; } - virtual std::vector> getBuffers() { std::vector> buffers; return buffers; } + virtual std::vector> getBuffers() + { + std::vector> buffers; + return buffers; + } /* Does renderer implement options dialog */ virtual bool hasOptions() const { return false; } /* Returns options dialog for renderer */ virtual QDialog *getOptions(QWidget *parent) { return nullptr; } /* Reloads options of renderer */ - virtual void reloadOptions() {} + virtual void reloadOptions() { } virtual bool hasBlitFunc() { return false; } - virtual void blit(int x, int y, int w, int h) {} + virtual void blit(int x, int y, int w, int h) { } protected: bool eventDelegate(QEvent *event, bool &result); - QRect source{0, 0, 0, 0}, destination; + QRect source { 0, 0, 0, 0 }, destination; QWidget *parentWidget { nullptr }; std::vector buf_usage; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 2d32f24a8..d36a88f86 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -26,7 +26,7 @@ #include "qt_softwarerenderer.hpp" #include "qt_vulkanwindowrenderer.hpp" #ifdef Q_OS_WIN -#include "qt_d3d9renderer.hpp" +# include "qt_d3d9renderer.hpp" #endif #include "qt_mainwindow.hpp" @@ -63,7 +63,7 @@ struct mouseinputdata { }; static mouseinputdata mousedata; -extern "C" void macos_poll_mouse(); +extern "C" void macos_poll_mouse(); extern MainWindow *main_window; RendererStack::RendererStack(QWidget *parent, int monitor_index) : QStackedWidget(parent) @@ -89,8 +89,8 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) # ifdef WAYLAND if (!stricmp(mouse_type, "wayland")) { wl_init(); - this->mouse_poll_func = wl_mouse_poll; - this->mouse_capture_func = wl_mouse_capture; + this->mouse_poll_func = wl_mouse_poll; + this->mouse_capture_func = wl_mouse_capture; this->mouse_uncapture_func = wl_mouse_uncapture; } # endif @@ -146,7 +146,7 @@ RendererStack::mousePoll() mouse_y = mousedata.deltay; mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; + mouse_buttons = mousedata.mousebuttons; if (this->mouse_poll_func) #endif @@ -258,10 +258,10 @@ RendererStack::switchRenderer(Renderer renderer) startblit(); if (current) { if ((current_vid_api == Renderer::Direct3D9 && renderer != Renderer::Direct3D9) - || (current_vid_api != Renderer::Direct3D9 && renderer == Renderer::Direct3D9)) { + || (current_vid_api != Renderer::Direct3D9 && renderer == Renderer::Direct3D9)) { rendererWindow->finalize(); if (rendererWindow->hasBlitFunc()) { - while (directBlitting) {} + while (directBlitting) { } connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); disconnect(this, &RendererStack::blit, this, &RendererStack::blitRenderer); } else { @@ -277,7 +277,7 @@ RendererStack::switchRenderer(Renderer renderer) createRenderer(renderer); disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy); blitDummied = false; - QTimer::singleShot(1000, this, [this]() { blitDummied = false; } ); + QTimer::singleShot(1000, this, [this]() { blitDummied = false; }); }); rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater(); @@ -354,65 +354,64 @@ RendererStack::createRenderer(Renderer renderer) } #ifdef Q_OS_WIN case Renderer::Direct3D9: - { - this->createWinId(); - auto hw = new D3D9Renderer(this, m_monitor_index); - rendererWindow = hw; - connect(hw, &D3D9Renderer::error, this, [this](QString str) { - auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->show(); - imagebufs = {}; - QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); - }); - connect(hw, &D3D9Renderer::initialized, this, [this]() - { - endblit(); - emit rendererChanged(); - }); - current.reset(hw); - break; - } + this->createWinId(); + auto hw = new D3D9Renderer(this, m_monitor_index); + rendererWindow = hw; + connect(hw, &D3D9Renderer::error, this, [this](QString str) { + auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->show(); + imagebufs = {}; + QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); + }); + connect(hw, &D3D9Renderer::initialized, this, [this]() { + endblit(); + emit rendererChanged(); + }); + current.reset(hw); + break; + } #endif #if QT_CONFIG(vulkan) case Renderer::Vulkan: - { - this->createWinId(); - VulkanWindowRenderer *hw = nullptr; - try { - hw = new VulkanWindowRenderer(this); - } catch(std::runtime_error& e) { - auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", e.what() + QString("\nFalling back to software rendering."), QMessageBox::Ok); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->show(); - imagebufs = {}; - QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); - current.reset(nullptr); + { + this->createWinId(); + VulkanWindowRenderer *hw = nullptr; + try { + hw = new VulkanWindowRenderer(this); + } catch (std::runtime_error &e) { + auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", e.what() + QString("\nFalling back to software rendering."), QMessageBox::Ok); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->show(); + imagebufs = {}; + QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); + current.reset(nullptr); + break; + }; + rendererWindow = hw; + connect(this, &RendererStack::blitToRenderer, hw, &VulkanWindowRenderer::onBlit, Qt::QueuedConnection); + connect(hw, &VulkanWindowRenderer::rendererInitialized, [=]() { + /* Buffers are available only after initialization. */ + imagebufs = rendererWindow->getBuffers(); + endblit(); + emit rendererChanged(); + }); + connect(hw, &VulkanWindowRenderer::errorInitializing, [=]() { + /* Renderer could not initialize, fallback to software. */ + auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize Vulkan renderer.\nFalling back to software rendering."), QMessageBox::Ok); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->show(); + imagebufs = {}; + QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); + }); + current.reset(this->createWindowContainer(hw, this)); break; - }; - rendererWindow = hw; - connect(this, &RendererStack::blitToRenderer, hw, &VulkanWindowRenderer::onBlit, Qt::QueuedConnection); - connect(hw, &VulkanWindowRenderer::rendererInitialized, [=]() { - /* Buffers are available only after initialization. */ - imagebufs = rendererWindow->getBuffers(); - endblit(); - emit rendererChanged(); - }); - connect(hw, &VulkanWindowRenderer::errorInitializing, [=]() { - /* Renderer could not initialize, fallback to software. */ - auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize Vulkan renderer.\nFalling back to software rendering."), QMessageBox::Ok); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->show(); - imagebufs = {}; - QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); - }); - current.reset(this->createWindowContainer(hw, this)); - break; - } + } #endif } - if (current.get() == nullptr) return; + if (current.get() == nullptr) + return; current->setFocusPolicy(Qt::NoFocus); current->setFocusProxy(this); current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -425,8 +424,7 @@ RendererStack::createRenderer(Renderer renderer) if (rendererWindow->hasBlitFunc()) { connect(this, &RendererStack::blit, this, &RendererStack::blitRenderer, Qt::DirectConnection); - } - else { + } else { connect(this, &RendererStack::blit, this, &RendererStack::blitCommon, Qt::DirectConnection); } @@ -447,7 +445,11 @@ RendererStack::blitDummy(int x, int y, int w, int h) void RendererStack::blitRenderer(int x, int y, int w, int h) { - if (blitDummied) { blitDummied = false; video_blit_complete_monitor(m_monitor_index); return; } + if (blitDummied) { + blitDummied = false; + video_blit_complete_monitor(m_monitor_index); + return; + } directBlitting = true; rendererWindow->blit(x, y, w, h); directBlitting = false; @@ -479,7 +481,8 @@ RendererStack::blitCommon(int x, int y, int w, int h) currentBuf = (currentBuf + 1) % imagebufs.size(); } -void RendererStack::closeEvent(QCloseEvent* event) +void +RendererStack::closeEvent(QCloseEvent *event) { if (cpu_thread_run == 1 || is_quit == 0) { event->accept(); @@ -490,7 +493,8 @@ void RendererStack::closeEvent(QCloseEvent* event) main_window->close(); } -void RendererStack::changeEvent(QEvent *event) +void +RendererStack::changeEvent(QEvent *event) { if (m_monitor_index != 0 && isVisible()) { monitor_settings[m_monitor_index].mon_window_maximized = isMaximized(); diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index 4d06ed1cf..baee5ea9f 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -32,7 +32,7 @@ public: void wheelEvent(QWheelEvent *event) override; void leaveEvent(QEvent *event) override; void closeEvent(QCloseEvent *event) override; - void changeEvent(QEvent* event) override; + void changeEvent(QEvent *event) override; void resizeEvent(QResizeEvent *event) override { onResize(event->size().width(), event->size().height()); @@ -75,10 +75,10 @@ public: rendererWindow->onResize(width, height); } - void (*mouse_poll_func)() = nullptr; + void (*mouse_poll_func)() = nullptr; void (*mouse_capture_func)(QWindow *window) = nullptr; - void (*mouse_uncapture_func)() = nullptr; - void (*mouse_exit_func)() = nullptr; + void (*mouse_uncapture_func)() = nullptr; + void (*mouse_exit_func)() = nullptr; signals: void blitToRenderer(int buf_idx, int x, int y, int w, int h); @@ -98,8 +98,8 @@ private: int x, y, w, h, sx, sy, sw, sh; - int currentBuf = 0; - int isMouseDown = 0; + int currentBuf = 0; + int isMouseDown = 0; int m_monitor_index = 0; Renderer current_vid_api = Renderer::None; @@ -108,7 +108,7 @@ private: RendererCommon *rendererWindow { nullptr }; std::unique_ptr current; - std::atomic directBlitting{false}; + std::atomic directBlitting { false }; }; #endif // QT_RENDERERCONTAINER_HPP diff --git a/src/qt/qt_sdl.c b/src/qt/qt_sdl.c index 57b9538e9..54eca952b 100644 --- a/src/qt/qt_sdl.c +++ b/src/qt/qt_sdl.c @@ -71,133 +71,130 @@ #include "qt_sdl.h" -#define RENDERER_FULL_SCREEN 1 -#define RENDERER_HARDWARE 2 -#define RENDERER_OPENGL 4 +#define RENDERER_FULL_SCREEN 1 +#define RENDERER_HARDWARE 2 +#define RENDERER_OPENGL 4 +static SDL_Window *sdl_win = NULL; +static SDL_Renderer *sdl_render = NULL; +static SDL_Texture *sdl_tex = NULL; +static int sdl_w, sdl_h; +static int sdl_fs, sdl_flags = -1; +static int cur_w, cur_h; +static int cur_ww = 0, cur_wh = 0; +static volatile int sdl_enabled = 0; +static SDL_mutex *sdl_mutex = NULL; -static SDL_Window *sdl_win = NULL; -static SDL_Renderer *sdl_render = NULL; -static SDL_Texture *sdl_tex = NULL; -static int sdl_w, sdl_h; -static int sdl_fs, sdl_flags = -1; -static int cur_w, cur_h; -static int cur_ww = 0, cur_wh = 0; -static volatile int sdl_enabled = 0; -static SDL_mutex* sdl_mutex = NULL; +static const uint16_t sdl_to_xt[0x200] = { + [SDL_SCANCODE_ESCAPE] = 0x01, + [SDL_SCANCODE_1] = 0x02, + [SDL_SCANCODE_2] = 0x03, + [SDL_SCANCODE_3] = 0x04, + [SDL_SCANCODE_4] = 0x05, + [SDL_SCANCODE_5] = 0x06, + [SDL_SCANCODE_6] = 0x07, + [SDL_SCANCODE_7] = 0x08, + [SDL_SCANCODE_8] = 0x09, + [SDL_SCANCODE_9] = 0x0A, + [SDL_SCANCODE_0] = 0x0B, + [SDL_SCANCODE_MINUS] = 0x0C, + [SDL_SCANCODE_EQUALS] = 0x0D, + [SDL_SCANCODE_BACKSPACE] = 0x0E, + [SDL_SCANCODE_TAB] = 0x0F, + [SDL_SCANCODE_Q] = 0x10, + [SDL_SCANCODE_W] = 0x11, + [SDL_SCANCODE_E] = 0x12, + [SDL_SCANCODE_R] = 0x13, + [SDL_SCANCODE_T] = 0x14, + [SDL_SCANCODE_Y] = 0x15, + [SDL_SCANCODE_U] = 0x16, + [SDL_SCANCODE_I] = 0x17, + [SDL_SCANCODE_O] = 0x18, + [SDL_SCANCODE_P] = 0x19, + [SDL_SCANCODE_LEFTBRACKET] = 0x1A, + [SDL_SCANCODE_RIGHTBRACKET] = 0x1B, + [SDL_SCANCODE_RETURN] = 0x1C, + [SDL_SCANCODE_LCTRL] = 0x1D, + [SDL_SCANCODE_A] = 0x1E, + [SDL_SCANCODE_S] = 0x1F, + [SDL_SCANCODE_D] = 0x20, + [SDL_SCANCODE_F] = 0x21, + [SDL_SCANCODE_G] = 0x22, + [SDL_SCANCODE_H] = 0x23, + [SDL_SCANCODE_J] = 0x24, + [SDL_SCANCODE_K] = 0x25, + [SDL_SCANCODE_L] = 0x26, + [SDL_SCANCODE_SEMICOLON] = 0x27, + [SDL_SCANCODE_APOSTROPHE] = 0x28, + [SDL_SCANCODE_GRAVE] = 0x29, + [SDL_SCANCODE_LSHIFT] = 0x2A, + [SDL_SCANCODE_BACKSLASH] = 0x2B, + [SDL_SCANCODE_Z] = 0x2C, + [SDL_SCANCODE_X] = 0x2D, + [SDL_SCANCODE_C] = 0x2E, + [SDL_SCANCODE_V] = 0x2F, + [SDL_SCANCODE_B] = 0x30, + [SDL_SCANCODE_N] = 0x31, + [SDL_SCANCODE_M] = 0x32, + [SDL_SCANCODE_COMMA] = 0x33, + [SDL_SCANCODE_PERIOD] = 0x34, + [SDL_SCANCODE_SLASH] = 0x35, + [SDL_SCANCODE_RSHIFT] = 0x36, + [SDL_SCANCODE_KP_MULTIPLY] = 0x37, + [SDL_SCANCODE_LALT] = 0x38, + [SDL_SCANCODE_SPACE] = 0x39, + [SDL_SCANCODE_CAPSLOCK] = 0x3A, + [SDL_SCANCODE_F1] = 0x3B, + [SDL_SCANCODE_F2] = 0x3C, + [SDL_SCANCODE_F3] = 0x3D, + [SDL_SCANCODE_F4] = 0x3E, + [SDL_SCANCODE_F5] = 0x3F, + [SDL_SCANCODE_F6] = 0x40, + [SDL_SCANCODE_F7] = 0x41, + [SDL_SCANCODE_F8] = 0x42, + [SDL_SCANCODE_F9] = 0x43, + [SDL_SCANCODE_F10] = 0x44, + [SDL_SCANCODE_NUMLOCKCLEAR] = 0x45, + [SDL_SCANCODE_SCROLLLOCK] = 0x46, + [SDL_SCANCODE_HOME] = 0x147, + [SDL_SCANCODE_UP] = 0x148, + [SDL_SCANCODE_PAGEUP] = 0x149, + [SDL_SCANCODE_KP_MINUS] = 0x4A, + [SDL_SCANCODE_LEFT] = 0x14B, + [SDL_SCANCODE_KP_5] = 0x4C, + [SDL_SCANCODE_RIGHT] = 0x14D, + [SDL_SCANCODE_KP_PLUS] = 0x4E, + [SDL_SCANCODE_END] = 0x14F, + [SDL_SCANCODE_DOWN] = 0x150, + [SDL_SCANCODE_PAGEDOWN] = 0x151, + [SDL_SCANCODE_INSERT] = 0x152, + [SDL_SCANCODE_DELETE] = 0x153, + [SDL_SCANCODE_F11] = 0x57, + [SDL_SCANCODE_F12] = 0x58, -static const uint16_t sdl_to_xt[0x200] = - { - [SDL_SCANCODE_ESCAPE] = 0x01, - [SDL_SCANCODE_1] = 0x02, - [SDL_SCANCODE_2] = 0x03, - [SDL_SCANCODE_3] = 0x04, - [SDL_SCANCODE_4] = 0x05, - [SDL_SCANCODE_5] = 0x06, - [SDL_SCANCODE_6] = 0x07, - [SDL_SCANCODE_7] = 0x08, - [SDL_SCANCODE_8] = 0x09, - [SDL_SCANCODE_9] = 0x0A, - [SDL_SCANCODE_0] = 0x0B, - [SDL_SCANCODE_MINUS] = 0x0C, - [SDL_SCANCODE_EQUALS] = 0x0D, - [SDL_SCANCODE_BACKSPACE] = 0x0E, - [SDL_SCANCODE_TAB] = 0x0F, - [SDL_SCANCODE_Q] = 0x10, - [SDL_SCANCODE_W] = 0x11, - [SDL_SCANCODE_E] = 0x12, - [SDL_SCANCODE_R] = 0x13, - [SDL_SCANCODE_T] = 0x14, - [SDL_SCANCODE_Y] = 0x15, - [SDL_SCANCODE_U] = 0x16, - [SDL_SCANCODE_I] = 0x17, - [SDL_SCANCODE_O] = 0x18, - [SDL_SCANCODE_P] = 0x19, - [SDL_SCANCODE_LEFTBRACKET] = 0x1A, - [SDL_SCANCODE_RIGHTBRACKET] = 0x1B, - [SDL_SCANCODE_RETURN] = 0x1C, - [SDL_SCANCODE_LCTRL] = 0x1D, - [SDL_SCANCODE_A] = 0x1E, - [SDL_SCANCODE_S] = 0x1F, - [SDL_SCANCODE_D] = 0x20, - [SDL_SCANCODE_F] = 0x21, - [SDL_SCANCODE_G] = 0x22, - [SDL_SCANCODE_H] = 0x23, - [SDL_SCANCODE_J] = 0x24, - [SDL_SCANCODE_K] = 0x25, - [SDL_SCANCODE_L] = 0x26, - [SDL_SCANCODE_SEMICOLON] = 0x27, - [SDL_SCANCODE_APOSTROPHE] = 0x28, - [SDL_SCANCODE_GRAVE] = 0x29, - [SDL_SCANCODE_LSHIFT] = 0x2A, - [SDL_SCANCODE_BACKSLASH] = 0x2B, - [SDL_SCANCODE_Z] = 0x2C, - [SDL_SCANCODE_X] = 0x2D, - [SDL_SCANCODE_C] = 0x2E, - [SDL_SCANCODE_V] = 0x2F, - [SDL_SCANCODE_B] = 0x30, - [SDL_SCANCODE_N] = 0x31, - [SDL_SCANCODE_M] = 0x32, - [SDL_SCANCODE_COMMA] = 0x33, - [SDL_SCANCODE_PERIOD] = 0x34, - [SDL_SCANCODE_SLASH] = 0x35, - [SDL_SCANCODE_RSHIFT] = 0x36, - [SDL_SCANCODE_KP_MULTIPLY] = 0x37, - [SDL_SCANCODE_LALT] = 0x38, - [SDL_SCANCODE_SPACE] = 0x39, - [SDL_SCANCODE_CAPSLOCK] = 0x3A, - [SDL_SCANCODE_F1] = 0x3B, - [SDL_SCANCODE_F2] = 0x3C, - [SDL_SCANCODE_F3] = 0x3D, - [SDL_SCANCODE_F4] = 0x3E, - [SDL_SCANCODE_F5] = 0x3F, - [SDL_SCANCODE_F6] = 0x40, - [SDL_SCANCODE_F7] = 0x41, - [SDL_SCANCODE_F8] = 0x42, - [SDL_SCANCODE_F9] = 0x43, - [SDL_SCANCODE_F10] = 0x44, - [SDL_SCANCODE_NUMLOCKCLEAR] = 0x45, - [SDL_SCANCODE_SCROLLLOCK] = 0x46, - [SDL_SCANCODE_HOME] = 0x147, - [SDL_SCANCODE_UP] = 0x148, - [SDL_SCANCODE_PAGEUP] = 0x149, - [SDL_SCANCODE_KP_MINUS] = 0x4A, - [SDL_SCANCODE_LEFT] = 0x14B, - [SDL_SCANCODE_KP_5] = 0x4C, - [SDL_SCANCODE_RIGHT] = 0x14D, - [SDL_SCANCODE_KP_PLUS] = 0x4E, - [SDL_SCANCODE_END] = 0x14F, - [SDL_SCANCODE_DOWN] = 0x150, - [SDL_SCANCODE_PAGEDOWN] = 0x151, - [SDL_SCANCODE_INSERT] = 0x152, - [SDL_SCANCODE_DELETE] = 0x153, - [SDL_SCANCODE_F11] = 0x57, - [SDL_SCANCODE_F12] = 0x58, + [SDL_SCANCODE_KP_ENTER] = 0x11c, + [SDL_SCANCODE_RCTRL] = 0x11d, + [SDL_SCANCODE_KP_DIVIDE] = 0x135, + [SDL_SCANCODE_RALT] = 0x138, + [SDL_SCANCODE_KP_9] = 0x49, + [SDL_SCANCODE_KP_8] = 0x48, + [SDL_SCANCODE_KP_7] = 0x47, + [SDL_SCANCODE_KP_6] = 0x4D, + [SDL_SCANCODE_KP_4] = 0x4B, + [SDL_SCANCODE_KP_3] = 0x51, + [SDL_SCANCODE_KP_2] = 0x50, + [SDL_SCANCODE_KP_1] = 0x4F, + [SDL_SCANCODE_KP_0] = 0x52, + [SDL_SCANCODE_KP_PERIOD] = 0x53, - [SDL_SCANCODE_KP_ENTER] = 0x11c, - [SDL_SCANCODE_RCTRL] = 0x11d, - [SDL_SCANCODE_KP_DIVIDE] = 0x135, - [SDL_SCANCODE_RALT] = 0x138, - [SDL_SCANCODE_KP_9] = 0x49, - [SDL_SCANCODE_KP_8] = 0x48, - [SDL_SCANCODE_KP_7] = 0x47, - [SDL_SCANCODE_KP_6] = 0x4D, - [SDL_SCANCODE_KP_4] = 0x4B, - [SDL_SCANCODE_KP_3] = 0x51, - [SDL_SCANCODE_KP_2] = 0x50, - [SDL_SCANCODE_KP_1] = 0x4F, - [SDL_SCANCODE_KP_0] = 0x52, - [SDL_SCANCODE_KP_PERIOD] = 0x53, - - [SDL_SCANCODE_LGUI] = 0x15B, - [SDL_SCANCODE_RGUI] = 0x15C, - [SDL_SCANCODE_APPLICATION] = 0x15D, - [SDL_SCANCODE_PRINTSCREEN] = 0x137, - [SDL_SCANCODE_NONUSBACKSLASH] = 0x56, + [SDL_SCANCODE_LGUI] = 0x15B, + [SDL_SCANCODE_RGUI] = 0x15C, + [SDL_SCANCODE_APPLICATION] = 0x15D, + [SDL_SCANCODE_PRINTSCREEN] = 0x137, + [SDL_SCANCODE_NONUSBACKSLASH] = 0x56, }; -typedef struct mouseinputdata -{ +typedef struct mouseinputdata { int deltax, deltay, deltaz; int mousebuttons; } mouseinputdata; @@ -213,88 +210,86 @@ sdl_log(const char *fmt, ...) va_list ap; if (sdl_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define sdl_log(fmt, ...) +# define sdl_log(fmt, ...) #endif - static void sdl_integer_scale(double *d, double *g) { double ratio; if (*d > *g) { - ratio = floor(*d / *g); - *d = *g * ratio; + ratio = floor(*d / *g); + *d = *g * ratio; } else { - ratio = ceil(*d / *g); - *d = *g / ratio; + ratio = ceil(*d / *g); + *d = *g / ratio; } } - static void sdl_stretch(int *w, int *h, int *x, int *y) { double hw, gw, hh, gh, dx, dy, dw, dh, gsr, hsr; - hw = (double) sdl_w; - hh = (double) sdl_h; - gw = (double) *w; - gh = (double) *h; + hw = (double) sdl_w; + hh = (double) sdl_h; + gw = (double) *w; + gh = (double) *h; hsr = hw / hh; switch (video_fullscreen_scale) { - case FULLSCR_SCALE_FULL: - default: - *w = sdl_w; - *h = sdl_h; - *x = 0; - *y = 0; - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) - gsr = 4.0 / 3.0; - else - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - sdl_integer_scale(&dw, &gw); - sdl_integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; + case FULLSCR_SCALE_FULL: + default: + *w = sdl_w; + *h = sdl_h; + *x = 0; + *y = 0; + break; + case FULLSCR_SCALE_43: + case FULLSCR_SCALE_KEEPRATIO: + if (video_fullscreen_scale == FULLSCR_SCALE_43) + gsr = 4.0 / 3.0; + else + gsr = gw / gh; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; + case FULLSCR_SCALE_INT: + gsr = gw / gh; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + sdl_integer_scale(&dw, &gw); + sdl_integer_scale(&dh, &gh); + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; } } @@ -302,8 +297,8 @@ static void sdl_blit(int x, int y, int w, int h) { SDL_Rect r_src; - void *pixeldata; - int ret, pitch; + void *pixeldata; + int ret, pitch; if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { video_blit_complete(); @@ -338,48 +333,45 @@ sdl_blit(int x, int y, int w, int h) SDL_UnlockMutex(sdl_mutex); } - static void sdl_destroy_window(void) { if (sdl_win != NULL) { - SDL_DestroyWindow(sdl_win); - sdl_win = NULL; + SDL_DestroyWindow(sdl_win); + sdl_win = NULL; } } - static void sdl_destroy_texture(void) { if (sdl_tex != NULL) { - SDL_DestroyTexture(sdl_tex); - sdl_tex = NULL; + SDL_DestroyTexture(sdl_tex); + sdl_tex = NULL; } /* SDL_DestroyRenderer also automatically destroys all associated textures. */ if (sdl_render != NULL) { - SDL_DestroyRenderer(sdl_render); - sdl_render = NULL; + SDL_DestroyRenderer(sdl_render); + sdl_render = NULL; } } - void sdl_close(void) { if (sdl_mutex != NULL) - SDL_LockMutex(sdl_mutex); + SDL_LockMutex(sdl_mutex); /* Unregister our renderer! */ video_setblit(NULL); if (sdl_enabled) - sdl_enabled = 0; + sdl_enabled = 0; if (sdl_mutex != NULL) { - SDL_DestroyMutex(sdl_mutex); - sdl_mutex = NULL; + SDL_DestroyMutex(sdl_mutex); + sdl_mutex = NULL; } sdl_destroy_texture(); @@ -390,8 +382,10 @@ sdl_close(void) sdl_flags = -1; } -static void sdl_select_best_hw_driver(void) { - int i; +static void +sdl_select_best_hw_driver(void) +{ + int i; SDL_RendererInfo renderInfo; for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { @@ -414,7 +408,7 @@ sdl_init_texture(void) } sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, (2048), (2048)); + SDL_TEXTUREACCESS_STREAMING, (2048), (2048)); if (sdl_render == NULL) { sdl_log("SDL: unable to SDL_CreateRenderer (%s)\n", SDL_GetError()); @@ -424,7 +418,6 @@ sdl_init_texture(void) } } - static void sdl_reinit_texture(void) { @@ -435,10 +428,11 @@ sdl_reinit_texture(void) sdl_init_texture(); } - -void sdl_set_fs(int fs) { +void +sdl_set_fs(int fs) +{ SDL_SetWindowFullscreen(sdl_win, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - SDL_SetRelativeMouseMode((SDL_bool)mouse_capture); + SDL_SetRelativeMouseMode((SDL_bool) mouse_capture); sdl_fs = fs; @@ -451,11 +445,10 @@ void sdl_set_fs(int fs) { sdl_reinit_texture(); } - static int -sdl_init_common(void* win, int flags) +sdl_init_common(void *win, int flags) { - wchar_t temp[128]; + wchar_t temp[128]; SDL_version ver; sdl_log("SDL: init (fs=%d)\n", 0); @@ -467,7 +460,7 @@ sdl_init_common(void* win, int flags) /* Initialize the SDL system. */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { sdl_log("SDL: initialization failed (%s)\n", SDL_GetError()); - return(0); + return (0); } if (flags & RENDERER_HARDWARE) { @@ -481,10 +474,10 @@ sdl_init_common(void* win, int flags) SDL_DisplayMode dm; if (SDL_GetDesktopDisplayMode(0, &dm) != 0) { sdl_log("SDL: SDL_GetDesktopDisplayMode failed (%s)\n", SDL_GetError()); - return(0); + return (0); } - sdl_w = dm.w; - sdl_h = dm.h; + sdl_w = dm.w; + sdl_h = dm.h; sdl_flags = flags; sdl_win = SDL_CreateWindow("86Box renderer", 640, 480, 100, 100, sdl_flags); @@ -501,50 +494,45 @@ sdl_init_common(void* win, int flags) video_setblit(sdl_blit); sdl_enabled = 1; - sdl_mutex = SDL_CreateMutex(); + sdl_mutex = SDL_CreateMutex(); - return(1); + return (1); } - int -sdl_inits(void* win) +sdl_inits(void *win) { return sdl_init_common(win, 0); } - int -sdl_inith(void* win) +sdl_inith(void *win) { return sdl_init_common(win, RENDERER_HARDWARE); } - int -sdl_initho(void* win) +sdl_initho(void *win) { return sdl_init_common(win, RENDERER_HARDWARE | RENDERER_OPENGL); } - int sdl_pause(void) { - return(0); + return (0); } - void sdl_resize(int w, int h) { int ww = 0, wh = 0; if (video_fullscreen & 2) - return; + return; if ((w == cur_w) && (h == cur_h)) - return; + return; SDL_LockMutex(sdl_mutex); @@ -552,8 +540,8 @@ sdl_resize(int w, int h) wh = h; if (sdl_fs) { -// sdl_stretch(&ww, &wh, &wx, &wy); -// MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); + // sdl_stretch(&ww, &wh, &wx, &wy); + // MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); } cur_w = w; @@ -568,12 +556,11 @@ sdl_resize(int w, int h) SDL_UnlockMutex(sdl_mutex); } - void sdl_enable(int enable) { if (sdl_flags == -1) - return; + return; SDL_LockMutex(sdl_mutex); sdl_enabled = !!enable; @@ -586,126 +573,115 @@ sdl_enable(int enable) SDL_UnlockMutex(sdl_mutex); } - void sdl_reload(void) { if (sdl_flags & RENDERER_HARDWARE) { - SDL_LockMutex(sdl_mutex); + SDL_LockMutex(sdl_mutex); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - sdl_reinit_texture(); + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); + sdl_reinit_texture(); - SDL_UnlockMutex(sdl_mutex); + SDL_UnlockMutex(sdl_mutex); } } static int mouse_inside = 0; -enum sdl_main_status sdl_main() { - int ret = SdlMainOk; - SDL_Rect r_src; +enum sdl_main_status +sdl_main() +{ + int ret = SdlMainOk; + SDL_Rect r_src; SDL_Event event; - while (SDL_PollEvent(&event)) - { - switch(event.type) - { - case SDL_QUIT: - ret = SdlMainQuit; - break; - case SDL_MOUSEWHEEL: - { - if (mouse_capture || video_fullscreen) - { - if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + ret = SdlMainQuit; + break; + case SDL_MOUSEWHEEL: { - event.wheel.x *= -1; - event.wheel.y *= -1; + if (mouse_capture || video_fullscreen) { + if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) { + event.wheel.x *= -1; + event.wheel.y *= -1; + } + mousedata.deltaz = event.wheel.y; + } + break; } - mousedata.deltaz = event.wheel.y; - } - break; - } - case SDL_MOUSEMOTION: - { - if (mouse_capture || video_fullscreen) - { - mousedata.deltax += event.motion.xrel; - mousedata.deltay += event.motion.yrel; - } - break; - } - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - { - if ((event.button.button == SDL_BUTTON_LEFT) - && !(mouse_capture || video_fullscreen) - && event.button.state == SDL_RELEASED - && mouse_inside) - { - plat_mouse_capture(1); - break; - } - if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) - { - plat_mouse_capture(0); - break; - } - if (mouse_capture || video_fullscreen) - { - int buttonmask = 0; + case SDL_MOUSEMOTION: + { + if (mouse_capture || video_fullscreen) { + mousedata.deltax += event.motion.xrel; + mousedata.deltay += event.motion.yrel; + } + break; + } + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + { + if ((event.button.button == SDL_BUTTON_LEFT) + && !(mouse_capture || video_fullscreen) + && event.button.state == SDL_RELEASED + && mouse_inside) { + plat_mouse_capture(1); + break; + } + if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) { + plat_mouse_capture(0); + break; + } + if (mouse_capture || video_fullscreen) { + int buttonmask = 0; - switch(event.button.button) - { - case SDL_BUTTON_LEFT: - buttonmask = 1; - break; - case SDL_BUTTON_RIGHT: - buttonmask = 2; - break; - case SDL_BUTTON_MIDDLE: - buttonmask = 4; + switch (event.button.button) { + case SDL_BUTTON_LEFT: + buttonmask = 1; + break; + case SDL_BUTTON_RIGHT: + buttonmask = 2; + break; + case SDL_BUTTON_MIDDLE: + buttonmask = 4; + break; + } + if (event.button.state == SDL_PRESSED) { + mousedata.mousebuttons |= buttonmask; + } else + mousedata.mousebuttons &= ~buttonmask; + } break; } - if (event.button.state == SDL_PRESSED) + case SDL_RENDER_DEVICE_RESET: + case SDL_RENDER_TARGETS_RESET: { - mousedata.mousebuttons |= buttonmask; + sdl_reinit_texture(); + break; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + uint16_t xtkey = 0; + switch (event.key.keysym.scancode) { + default: + xtkey = sdl_to_xt[event.key.keysym.scancode]; + break; + } + keyboard_input(event.key.state == SDL_PRESSED, xtkey); } - else mousedata.mousebuttons &= ~buttonmask; - } - break; - } - case SDL_RENDER_DEVICE_RESET: - case SDL_RENDER_TARGETS_RESET: - { - sdl_reinit_texture(); - break; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - uint16_t xtkey = 0; - switch(event.key.keysym.scancode) - { - default: - xtkey = sdl_to_xt[event.key.keysym.scancode]; break; - } - keyboard_input(event.key.state == SDL_PRESSED, xtkey); - } - break; - case SDL_WINDOWEVENT: - { - switch (event.window.event) - { - case SDL_WINDOWEVENT_ENTER: - mouse_inside = 1; - break; - case SDL_WINDOWEVENT_LEAVE: - mouse_inside = 0; - break; - } - } + case SDL_WINDOWEVENT: + { + switch (event.window.event) { + case SDL_WINDOWEVENT_ENTER: + mouse_inside = 1; + break; + case SDL_WINDOWEVENT_LEAVE: + mouse_inside = 0; + break; + } + } } } @@ -719,14 +695,18 @@ enum sdl_main_status sdl_main() { return ret; } -void sdl_mouse_capture(int on) { - SDL_SetRelativeMouseMode((SDL_bool)on); +void +sdl_mouse_capture(int on) +{ + SDL_SetRelativeMouseMode((SDL_bool) on); } -void sdl_mouse_poll() { - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; +void +sdl_mouse_poll() +{ + mouse_x = mousedata.deltax; + mouse_y = mousedata.deltay; + mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; + mouse_buttons = mousedata.mousebuttons; } diff --git a/src/qt/qt_sdl.h b/src/qt/qt_sdl.h index 02fd47ddf..684e6ccd0 100644 --- a/src/qt/qt_sdl.h +++ b/src/qt/qt_sdl.h @@ -47,18 +47,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef WIN_SDL_H -# define WIN_SDL_H +#define WIN_SDL_H -extern void* sdl_win_handle; -extern void sdl_close(void); -extern int sdl_inits(); -extern int sdl_inith(); -extern int sdl_initho(); -extern int sdl_pause(void); -extern void sdl_resize(int w, int h); -extern void sdl_enable(int enable); -extern void sdl_set_fs(int fs); -extern void sdl_reload(void); +extern void *sdl_win_handle; +extern void sdl_close(void); +extern int sdl_inits(); +extern int sdl_inith(); +extern int sdl_initho(); +extern int sdl_pause(void); +extern void sdl_resize(int w, int h); +extern void sdl_enable(int enable); +extern void sdl_set_fs(int fs); +extern void sdl_reload(void); enum sdl_main_status { SdlMainOk, @@ -70,4 +70,4 @@ extern enum sdl_main_status sdl_main(); extern void sdl_mouse_capture(int on); extern void sdl_mouse_poll(); -#endif /*WIN_SDL_H*/ +#endif /*WIN_SDL_H*/ diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index 290b95982..b42b20786 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -35,8 +35,7 @@ #include "qt_harddrive_common.hpp" #include "qt_settings_bus_tracking.hpp" -extern "C" -{ +extern "C" { #include <86box/86box.h> } @@ -48,10 +47,14 @@ extern "C" class SettingsModel : public QAbstractListModel { public: - SettingsModel(QObject* parent) : QAbstractListModel(parent) {} + SettingsModel(QObject *parent) + : QAbstractListModel(parent) + { + } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + private: QStringList pages = { "Machine", @@ -81,44 +84,49 @@ private: }; }; -QVariant SettingsModel::data(const QModelIndex &index, int role) const { +QVariant +SettingsModel::data(const QModelIndex &index, int role) const +{ Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid | QAbstractItemModel::CheckIndexOption::ParentIsInvalid)); switch (role) { - case Qt::DisplayRole: - return tr(pages.at(index.row()).toUtf8().data()); - case Qt::DecorationRole: - return QIcon(QString("%1/%2.ico").arg(ProgSettings::getIconSetPath(), page_icons[index.row()])); - default: - return {}; + case Qt::DisplayRole: + return tr(pages.at(index.row()).toUtf8().data()); + case Qt::DecorationRole: + return QIcon(QString("%1/%2.ico").arg(ProgSettings::getIconSetPath(), page_icons[index.row()])); + default: + return {}; } } -int SettingsModel::rowCount(const QModelIndex &parent) const { +int +SettingsModel::rowCount(const QModelIndex &parent) const +{ (void) parent; return pages.size(); } -Settings* Settings::settings = nullptr;; -Settings::Settings(QWidget *parent) : - QDialog(parent), - ui(new Ui::Settings) +Settings *Settings::settings = nullptr; +; +Settings::Settings(QWidget *parent) + : QDialog(parent) + , ui(new Ui::Settings) { ui->setupUi(this); ui->listView->setModel(new SettingsModel(this)); Harddrives::busTrackClass = new SettingsBusTracking; - machine = new SettingsMachine(this); - display = new SettingsDisplay(this); - input = new SettingsInput(this); - sound = new SettingsSound(this); - network = new SettingsNetwork(this); - ports = new SettingsPorts(this); - storageControllers = new SettingsStorageControllers(this); - harddisks = new SettingsHarddisks(this); - floppyCdrom = new SettingsFloppyCDROM(this); - otherRemovable = new SettingsOtherRemovable(this); - otherPeripherals = new SettingsOtherPeripherals(this); + machine = new SettingsMachine(this); + display = new SettingsDisplay(this); + input = new SettingsInput(this); + sound = new SettingsSound(this); + network = new SettingsNetwork(this); + ports = new SettingsPorts(this); + storageControllers = new SettingsStorageControllers(this); + harddisks = new SettingsHarddisks(this); + floppyCdrom = new SettingsFloppyCDROM(this); + otherRemovable = new SettingsOtherRemovable(this); + otherPeripherals = new SettingsOtherPeripherals(this); ui->stackedWidget->addWidget(machine); ui->stackedWidget->addWidget(display); @@ -153,10 +161,12 @@ Settings::~Settings() delete ui; delete Harddrives::busTrackClass; Harddrives::busTrackClass = nullptr; - Settings::settings = nullptr; + Settings::settings = nullptr; } -void Settings::save() { +void +Settings::save() +{ machine->save(); display->save(); input->save(); @@ -170,12 +180,12 @@ void Settings::save() { otherPeripherals->save(); } -void Settings::accept() +void +Settings::accept() { - if (confirm_save && !settings_only) - { + if (confirm_save && !settings_only) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", QStringLiteral("%1\n\n%2").arg(tr("Do you want to save the settings?"), tr("This will hard reset the emulated machine.")), QMessageBox::Save | QMessageBox::Cancel, this); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_save); QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { diff --git a/src/qt/qt_settings.hpp b/src/qt/qt_settings.hpp index 7e0a78cfa..8603c42b6 100644 --- a/src/qt/qt_settings.hpp +++ b/src/qt/qt_settings.hpp @@ -19,32 +19,31 @@ class SettingsFloppyCDROM; class SettingsOtherRemovable; class SettingsOtherPeripherals; -class Settings : public QDialog -{ +class Settings : public QDialog { Q_OBJECT public: - explicit Settings(QWidget *parent = nullptr); + explicit Settings(QWidget *parent = nullptr); ~Settings(); - void save(); + void save(); - static Settings* settings; + static Settings *settings; protected slots: - void accept() override; + void accept() override; private: - Ui::Settings *ui; - SettingsMachine* machine; - SettingsDisplay* display; - SettingsInput* input; - SettingsSound* sound; - SettingsNetwork* network; - SettingsPorts* ports; - SettingsStorageControllers* storageControllers; - SettingsHarddisks* harddisks; - SettingsFloppyCDROM* floppyCdrom; - SettingsOtherRemovable* otherRemovable; - SettingsOtherPeripherals* otherPeripherals; + Ui::Settings *ui; + SettingsMachine *machine; + SettingsDisplay *display; + SettingsInput *input; + SettingsSound *sound; + SettingsNetwork *network; + SettingsPorts *ports; + SettingsStorageControllers *storageControllers; + SettingsHarddisks *harddisks; + SettingsFloppyCDROM *floppyCdrom; + SettingsOtherRemovable *otherRemovable; + SettingsOtherPeripherals *otherPeripherals; }; #endif // QT_SETTINGS_HPP diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp index a1d8e3369..c22b8b10b 100644 --- a/src/qt/qt_settings_bus_tracking.cpp +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -24,14 +24,13 @@ #include "86box/hdd.h" #include "qt_settings_bus_tracking.hpp" - SettingsBusTracking::SettingsBusTracking() { int i; - mfm_tracking = 0x0000000000000000ULL; + mfm_tracking = 0x0000000000000000ULL; esdi_tracking = 0x0000000000000000ULL; - xta_tracking = 0x0000000000000000ULL; + xta_tracking = 0x0000000000000000ULL; for (i = 0; i < 8; i++) { if (i < 4) @@ -41,7 +40,6 @@ SettingsBusTracking::SettingsBusTracking() } } - uint8_t SettingsBusTracking::next_free_mfm_channel() { @@ -54,7 +52,6 @@ SettingsBusTracking::next_free_mfm_channel() return CHANNEL_NONE; } - uint8_t SettingsBusTracking::next_free_esdi_channel() { @@ -67,7 +64,6 @@ SettingsBusTracking::next_free_esdi_channel() return CHANNEL_NONE; } - uint8_t SettingsBusTracking::next_free_xta_channel() { @@ -80,145 +76,137 @@ SettingsBusTracking::next_free_xta_channel() return CHANNEL_NONE; } - uint8_t SettingsBusTracking::next_free_ide_channel() { - int i, element; + int i, element; uint64_t mask; - uint8_t ret = CHANNEL_NONE; + uint8_t ret = CHANNEL_NONE; for (i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (!(ide_tracking[element] & mask)) { - ret = (uint8_t) i; - break; + ret = (uint8_t) i; + break; } } return ret; } - uint8_t SettingsBusTracking::next_free_scsi_id() { - int i, element; + int i, element; uint64_t mask; - uint8_t ret = CHANNEL_NONE; + uint8_t ret = CHANNEL_NONE; for (i = 0; i < 64; i++) { element = ((i << 3) >> 6); - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (!(scsi_tracking[element] & mask)) { - ret = (uint8_t) i; - break; + ret = (uint8_t) i; + break; } } return ret; } - int SettingsBusTracking::mfm_bus_full() { - int i; + int i; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 2; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (mfm_tracking & mask) - count++; + count++; } return (count == 2); } - int SettingsBusTracking::esdi_bus_full() { - int i; + int i; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 2; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (esdi_tracking & mask) - count++; + count++; } return (count == 2); } - int SettingsBusTracking::xta_bus_full() { - int i; + int i; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 2; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (xta_tracking & mask) - count++; + count++; } return (count == 2); } - int SettingsBusTracking::ide_bus_full() { - int i, element; + int i, element; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (ide_tracking[element] & mask) - count++; + count++; } return (count == 32); } - int SettingsBusTracking::scsi_bus_full() { - int i, element; + int i, element; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 64; i++) { element = ((i << 3) >> 6); - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (scsi_tracking[element] & mask) - count++; + count++; } return (count == 64); } - void SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channel) { - int element; + int element; uint64_t mask; switch (bus) { @@ -252,7 +240,7 @@ SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channe case HDD_BUS_IDE: case HDD_BUS_ATAPI: element = ((channel << 3) >> 6); - mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); if (set) ide_tracking[element] |= mask; @@ -262,7 +250,7 @@ SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channe case HDD_BUS_SCSI: element = ((channel << 3) >> 6); - mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); if (set) scsi_tracking[element] |= mask; diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index 0272b4359..fb878b716 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -3,28 +3,27 @@ #include -#define TRACK_CLEAR 0 -#define TRACK_SET 1 +#define TRACK_CLEAR 0 +#define TRACK_SET 1 -#define DEV_HDD 0x01 -#define DEV_CDROM 0x02 -#define DEV_ZIP 0x04 -#define DEV_MO 0x08 +#define DEV_HDD 0x01 +#define DEV_CDROM 0x02 +#define DEV_ZIP 0x04 +#define DEV_MO 0x08 -#define BUS_MFM 0 -#define BUS_ESDI 1 -#define BUS_XTA 2 -#define BUS_IDE 3 -#define BUS_SCSI 4 +#define BUS_MFM 0 +#define BUS_ESDI 1 +#define BUS_XTA 2 +#define BUS_IDE 3 +#define BUS_SCSI 4 -#define CHANNEL_NONE 0xff +#define CHANNEL_NONE 0xff namespace Ui { class SettingsBusTracking; } -class SettingsBusTracking -{ +class SettingsBusTracking { public: explicit SettingsBusTracking(); ~SettingsBusTracking() = default; @@ -49,15 +48,15 @@ public: private: /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t mfm_tracking{0}; + uint64_t mfm_tracking { 0 }; /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t esdi_tracking{0}; + uint64_t esdi_tracking { 0 }; /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t xta_tracking{0}; + uint64_t xta_tracking { 0 }; /* 16 channels (prepatation for that weird IDE card), 2 devices per channel, 8 bits per device = 256 bits. */ - uint64_t ide_tracking[4]{0, 0, 0, 0}; + uint64_t ide_tracking[4] { 0, 0, 0, 0 }; /* 4 buses, 16 devices per bus, 8 bits per device (future-proofing) = 512 bits. */ - uint64_t scsi_tracking[8]{0, 0, 0, 0, 0, 0, 0, 0}; + uint64_t scsi_tracking[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; }; #endif // QT_SETTINGS_BUS_TRACKING_HPP diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 84054806d..6ed9e7094 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -30,9 +30,9 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsDisplay::SettingsDisplay(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsDisplay) +SettingsDisplay::SettingsDisplay(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsDisplay) { ui->setupUi(this); @@ -44,22 +44,26 @@ SettingsDisplay::~SettingsDisplay() delete ui; } -void SettingsDisplay::save() { - gfxcard = ui->comboBoxVideo->currentData().toInt(); - gfxcard_2 = ui->comboBoxVideoSecondary->currentData().toInt(); - voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0; +void +SettingsDisplay::save() +{ + gfxcard = ui->comboBoxVideo->currentData().toInt(); + gfxcard_2 = ui->comboBoxVideoSecondary->currentData().toInt(); + voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0; ibm8514_enabled = ui->checkBox8514->isChecked() ? 1 : 0; - xga_enabled = ui->checkBoxXga->isChecked() ? 1 : 0; + xga_enabled = ui->checkBoxXga->isChecked() ? 1 : 0; } -void SettingsDisplay::onCurrentMachineChanged(int machineId) { +void +SettingsDisplay::onCurrentMachineChanged(int machineId) +{ // win_settings_video_proc, WM_INITDIALOG this->machineId = machineId; - auto* model = ui->comboBoxVideo->model(); - auto removeRows = model->rowCount(); + auto *model = ui->comboBoxVideo->model(); + auto removeRows = model->rowCount(); - int c = 0; + int c = 0; int selectedRow = 0; while (true) { /* Skip "internal" if machine doesn't have it. */ @@ -68,14 +72,13 @@ void SettingsDisplay::onCurrentMachineChanged(int machineId) { continue; } - const device_t* video_dev = video_card_getdevice(c); - QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); + const device_t *video_dev = video_card_getdevice(c); + QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); if (name.isEmpty()) { break; } - if (video_card_available(c) && - device_is_valid(video_dev, machineId)) { + if (video_card_available(c) && device_is_valid(video_dev, machineId)) { int row = Models::AddEntry(model, name, c); if (c == gfxcard) { selectedRow = row - removeRows; @@ -97,27 +100,36 @@ void SettingsDisplay::onCurrentMachineChanged(int machineId) { ui->pushButtonConfigureSecondary->setEnabled(true); } ui->comboBoxVideo->setCurrentIndex(selectedRow); - if (gfxcard_2 == 0) ui->pushButtonConfigureSecondary->setEnabled(false); + if (gfxcard_2 == 0) + ui->pushButtonConfigureSecondary->setEnabled(false); } -void SettingsDisplay::on_pushButtonConfigure_clicked() { - auto* device = video_card_getdevice(ui->comboBoxVideo->currentData().toInt()); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); +void +SettingsDisplay::on_pushButtonConfigure_clicked() +{ + auto *device = video_card_getdevice(ui->comboBoxVideo->currentData().toInt()); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } -void SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() { - DeviceConfig::ConfigureDevice(&voodoo_device, 0, qobject_cast(Settings::settings)); +void +SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() +{ + DeviceConfig::ConfigureDevice(&voodoo_device, 0, qobject_cast(Settings::settings)); } -void SettingsDisplay::on_pushButtonConfigureXga_clicked() { +void +SettingsDisplay::on_pushButtonConfigureXga_clicked() +{ if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { - DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast(Settings::settings)); } else { - DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast(Settings::settings)); } } -void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { +void +SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) +{ if (index < 0) { return; } @@ -132,7 +144,7 @@ void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { ui->pushButtonConfigureVoodoo->setEnabled(machineHasPci && ui->checkBoxVoodoo->isChecked()); bool hasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0; - bool has_MCA = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0; + bool has_MCA = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0; ui->checkBox8514->setEnabled(hasIsa16 || has_MCA); if (hasIsa16 || has_MCA) { ui->checkBox8514->setChecked(ibm8514_enabled); @@ -156,39 +168,41 @@ void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { return; } while (true) { - const device_t* video_dev = video_card_getdevice(c); - QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); + const device_t *video_dev = video_card_getdevice(c); + QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); if (name.isEmpty()) { break; } - if (video_card_available(c) && - device_is_valid(video_dev, machineId) && - !(video_card_get_flags(c) == video_card_get_flags(videoCard))) { - ui->comboBoxVideoSecondary->addItem(name, c); - if (c == gfxcard_2) - ui->comboBoxVideoSecondary->setCurrentIndex(ui->comboBoxVideoSecondary->count() - 1); + if (video_card_available(c) && device_is_valid(video_dev, machineId) && !(video_card_get_flags(c) == video_card_get_flags(videoCard))) { + ui->comboBoxVideoSecondary->addItem(name, c); + if (c == gfxcard_2) + ui->comboBoxVideoSecondary->setCurrentIndex(ui->comboBoxVideoSecondary->count() - 1); } c++; } - if (gfxcard_2 == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) - { + if (gfxcard_2 == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) { ui->comboBoxVideoSecondary->setCurrentIndex(0); ui->pushButtonConfigureSecondary->setEnabled(false); } } -void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) { +void +SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) +{ ui->pushButtonConfigureVoodoo->setEnabled(state == Qt::Checked); } -void SettingsDisplay::on_checkBoxXga_stateChanged(int state) { +void +SettingsDisplay::on_checkBoxXga_stateChanged(int state) +{ ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked); } -void SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index) +void +SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index) { if (index < 0) { ui->pushButtonConfigureSecondary->setEnabled(false); @@ -198,10 +212,9 @@ void SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index) ui->pushButtonConfigureSecondary->setEnabled(index != 0 && video_card_has_config(videoCard) > 0); } - -void SettingsDisplay::on_pushButtonConfigureSecondary_clicked() +void +SettingsDisplay::on_pushButtonConfigureSecondary_clicked() { - auto* device = video_card_getdevice(ui->comboBoxVideoSecondary->currentData().toInt()); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + auto *device = video_card_getdevice(ui->comboBoxVideoSecondary->currentData().toInt()); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } - diff --git a/src/qt/qt_settingsdisplay.hpp b/src/qt/qt_settingsdisplay.hpp index 06badd656..0aab5c161 100644 --- a/src/qt/qt_settingsdisplay.hpp +++ b/src/qt/qt_settingsdisplay.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsDisplay; } -class SettingsDisplay : public QWidget -{ +class SettingsDisplay : public QWidget { Q_OBJECT public: @@ -36,7 +35,7 @@ private slots: private: Ui::SettingsDisplay *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSDISPLAY_HPP diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 32943f9a6..2eabe80ab 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -32,7 +32,9 @@ extern "C" { #include "qt_settings_bus_tracking.hpp" #include "qt_progsettings.hpp" -static void setFloppyType(QAbstractItemModel* model, const QModelIndex& idx, int type) { +static void +setFloppyType(QAbstractItemModel *model, const QModelIndex &idx, int type) +{ QIcon icon; if (type == 0) { icon = ProgSettings::loadIcon("/floppy_disabled.ico"); @@ -47,16 +49,18 @@ static void setFloppyType(QAbstractItemModel* model, const QModelIndex& idx, int model->setData(idx, icon, Qt::DecorationRole); } -static void setCDROMBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t bus, uint8_t channel) { +static void +setCDROMBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) +{ QIcon icon; switch (bus) { - case CDROM_BUS_DISABLED: - icon = ProgSettings::loadIcon("/cdrom_disabled.ico"); - break; - case CDROM_BUS_ATAPI: - case CDROM_BUS_SCSI: - icon = ProgSettings::loadIcon("/cdrom.ico"); - break; + case CDROM_BUS_DISABLED: + icon = ProgSettings::loadIcon("/cdrom_disabled.ico"); + break; + case CDROM_BUS_ATAPI: + case CDROM_BUS_SCSI: + icon = ProgSettings::loadIcon("/cdrom.ico"); + break; } auto i = idx.siblingAtColumn(0); @@ -66,27 +70,32 @@ static void setCDROMBus(QAbstractItemModel* model, const QModelIndex& idx, uint8 model->setData(i, icon, Qt::DecorationRole); } -static void setCDROMSpeed(QAbstractItemModel* model, const QModelIndex& idx, uint8_t speed) { - if (!speed) speed = 8; +static void +setCDROMSpeed(QAbstractItemModel *model, const QModelIndex &idx, uint8_t speed) +{ + if (!speed) + speed = 8; auto i = idx.siblingAtColumn(1); model->setData(i, QString("%1x").arg(speed)); model->setData(i, speed, Qt::UserRole); } -static void setCDROMEarly(QAbstractItemModel* model, const QModelIndex& idx, bool early) { +static void +setCDROMEarly(QAbstractItemModel *model, const QModelIndex &idx, bool early) +{ auto i = idx.siblingAtColumn(2); model->setData(i, (early == true) ? QObject::tr("On") : QObject::tr("Off")); model->setData(i, early, Qt::UserRole); } -SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsFloppyCDROM) +SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsFloppyCDROM) { ui->setupUi(this); - auto* model = ui->comboBoxFloppyType->model(); - int i = 0; + auto *model = ui->comboBoxFloppyType->model(); + int i = 0; while (true) { QString name = tr(fdd_getname(i)); if (name.isEmpty()) { @@ -106,8 +115,8 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) : model->insertRows(0, FDD_NUM); /* Floppy drives category */ for (int i = 0; i < FDD_NUM; i++) { - auto idx = model->index(i, 0); - int type = fdd_get_type(i); + auto idx = model->index(i, 0); + int type = fdd_get_type(i); setFloppyType(model, idx, type); model->setData(idx.siblingAtColumn(1), fdd_get_turbo(i) > 0 ? tr("On") : tr("Off")); model->setData(idx.siblingAtColumn(2), fdd_get_check_bpb(i) > 0 ? tr("On") : tr("Off")); @@ -119,7 +128,6 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) : connect(ui->tableViewFloppy->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsFloppyCDROM::onFloppyRowChanged); ui->tableViewFloppy->setCurrentIndex(model->index(0, 0)); - Harddrives::populateRemovableBuses(ui->comboBoxBus->model()); model = ui->comboBoxSpeed->model(); for (int i = 0; i < 72; i++) { @@ -151,8 +159,10 @@ SettingsFloppyCDROM::~SettingsFloppyCDROM() delete ui; } -void SettingsFloppyCDROM::save() { - auto* model = ui->tableViewFloppy->model(); +void +SettingsFloppyCDROM::save() +{ + auto *model = ui->tableViewFloppy->model(); for (int i = 0; i < FDD_NUM; i++) { fdd_set_type(i, model->index(i, 0).data(Qt::UserRole).toInt()); fdd_set_turbo(i, model->index(i, 1).data() == tr("On") ? 1 : 0); @@ -162,44 +172,48 @@ void SettingsFloppyCDROM::save() { /* Removable devices category */ model = ui->tableViewCDROM->model(); for (int i = 0; i < CDROM_NUM; i++) { - cdrom[i].is_dir = 0; - cdrom[i].priv = NULL; - cdrom[i].ops = NULL; - cdrom[i].image = NULL; - cdrom[i].insert = NULL; - cdrom[i].close = NULL; - cdrom[i].get_volume = NULL; + cdrom[i].is_dir = 0; + cdrom[i].priv = NULL; + cdrom[i].ops = NULL; + cdrom[i].image = NULL; + cdrom[i].insert = NULL; + cdrom[i].close = NULL; + cdrom[i].get_volume = NULL; cdrom[i].get_channel = NULL; - cdrom[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); - cdrom[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); - cdrom[i].speed = model->index(i, 1).data(Qt::UserRole).toUInt(); - cdrom[i].early = model->index(i, 2).data(Qt::UserRole).toUInt(); + cdrom[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); + cdrom[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + cdrom[i].speed = model->index(i, 1).data(Qt::UserRole).toUInt(); + cdrom[i].early = model->index(i, 2).data(Qt::UserRole).toUInt(); } } -void SettingsFloppyCDROM::onFloppyRowChanged(const QModelIndex ¤t) { +void +SettingsFloppyCDROM::onFloppyRowChanged(const QModelIndex ¤t) +{ int type = current.siblingAtColumn(0).data(Qt::UserRole).toInt(); ui->comboBoxFloppyType->setCurrentIndex(type); ui->checkBoxTurboTimings->setChecked(current.siblingAtColumn(1).data() == tr("On")); ui->checkBoxCheckBPB->setChecked(current.siblingAtColumn(2).data() == tr("On")); } -void SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) { - uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); +void +SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) +{ + uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); - uint8_t speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); - bool early = current.siblingAtColumn(2).data(Qt::UserRole).toBool(); + uint8_t speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); + bool early = current.siblingAtColumn(2).data(Qt::UserRole).toBool(); ui->comboBoxBus->setCurrentIndex(-1); - auto* model = ui->comboBoxBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (! match.isEmpty()) { + auto *model = ui->comboBoxBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) { ui->comboBoxBus->setCurrentIndex(match.first().row()); } model = ui->comboBoxChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxChannel->setCurrentIndex(match.first().row()); } @@ -207,26 +221,34 @@ void SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) { ui->checkBoxEarlierDrive->setChecked(early); } -void SettingsFloppyCDROM::on_checkBoxTurboTimings_stateChanged(int arg1) { +void +SettingsFloppyCDROM::on_checkBoxTurboTimings_stateChanged(int arg1) +{ auto idx = ui->tableViewFloppy->selectionModel()->currentIndex(); ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(1), arg1 == Qt::Checked ? tr("On") : tr("Off")); } -void SettingsFloppyCDROM::on_checkBoxCheckBPB_stateChanged(int arg1) { +void +SettingsFloppyCDROM::on_checkBoxCheckBPB_stateChanged(int arg1) +{ auto idx = ui->tableViewFloppy->selectionModel()->currentIndex(); ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(2), arg1 == Qt::Checked ? tr("On") : tr("Off")); } -void SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index) { +void +SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index) +{ setFloppyType(ui->tableViewFloppy->model(), ui->tableViewFloppy->selectionModel()->currentIndex(), index); } -void SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) { +void +SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) +{ if (index < 0) { return; } - int bus = ui->comboBoxBus->currentData().toInt(); + int bus = ui->comboBoxBus->currentData().toInt(); bool enabled = (bus != CDROM_BUS_DISABLED); ui->comboBoxChannel->setEnabled(enabled); ui->comboBoxSpeed->setEnabled(enabled); @@ -234,13 +256,16 @@ void SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) { Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus); } -void SettingsFloppyCDROM::on_comboBoxSpeed_activated(int index) { +void +SettingsFloppyCDROM::on_comboBoxSpeed_activated(int index) +{ auto idx = ui->tableViewCDROM->selectionModel()->currentIndex(); setCDROMSpeed(ui->tableViewCDROM->model(), idx.siblingAtColumn(1), index + 1); } - -void SettingsFloppyCDROM::on_comboBoxBus_activated(int) { +void +SettingsFloppyCDROM::on_comboBoxBus_activated(int) +{ auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); ui->comboBoxChannel->setCurrentIndex(ui->comboBoxBus->currentData().toUInt() == CDROM_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); @@ -252,8 +277,9 @@ void SettingsFloppyCDROM::on_comboBoxBus_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); } - -void SettingsFloppyCDROM::on_comboBoxChannel_activated(int) { +void +SettingsFloppyCDROM::on_comboBoxChannel_activated(int) +{ auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); setCDROMBus( @@ -264,9 +290,9 @@ void SettingsFloppyCDROM::on_comboBoxChannel_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsFloppyCDROM::on_checkBoxEarlierDrive_stateChanged(int arg1) +void +SettingsFloppyCDROM::on_checkBoxEarlierDrive_stateChanged(int arg1) { auto idx = ui->tableViewCDROM->selectionModel()->currentIndex(); setCDROMEarly(ui->tableViewCDROM->model(), idx.siblingAtColumn(2), (arg1 == Qt::Checked) ? true : false); } - diff --git a/src/qt/qt_settingsfloppycdrom.hpp b/src/qt/qt_settingsfloppycdrom.hpp index 4f50031cf..5c2920199 100644 --- a/src/qt/qt_settingsfloppycdrom.hpp +++ b/src/qt/qt_settingsfloppycdrom.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsFloppyCDROM; } -class SettingsFloppyCDROM : public QWidget -{ +class SettingsFloppyCDROM : public QWidget { Q_OBJECT public: diff --git a/src/qt/qt_settingsharddisks.cpp b/src/qt/qt_settingsharddisks.cpp index 0c3938c91..1883797e5 100644 --- a/src/qt/qt_settingsharddisks.cpp +++ b/src/qt/qt_settingsharddisks.cpp @@ -31,18 +31,18 @@ extern "C" { #include "qt_settings_bus_tracking.hpp" #include "qt_progsettings.hpp" -const int ColumnBus = 0; -const int ColumnFilename = 1; -const int ColumnCylinders = 2; -const int ColumnHeads = 3; -const int ColumnSectors = 4; -const int ColumnSize = 5; -const int ColumnSpeed = 6; +const int ColumnBus = 0; +const int ColumnFilename = 1; +const int ColumnCylinders = 2; +const int ColumnHeads = 3; +const int ColumnSectors = 4; +const int ColumnSize = 5; +const int ColumnSpeed = 6; -const int DataBus = Qt::UserRole; -const int DataBusChannel = Qt::UserRole + 1; -const int DataBusPrevious = Qt::UserRole + 2; -const int DataBusChannelPrevious = Qt::UserRole + 3; +const int DataBus = Qt::UserRole; +const int DataBusChannel = Qt::UserRole + 1; +const int DataBusPrevious = Qt::UserRole + 2; +const int DataBusChannelPrevious = Qt::UserRole + 3; /* static void @@ -65,11 +65,15 @@ normalize_hd_list() } */ -static QString busChannelName(const QModelIndex& idx) { +static QString +busChannelName(const QModelIndex &idx) +{ return Harddrives::BusChannelName(idx.data(DataBus).toUInt(), idx.data(DataBusChannel).toUInt()); } -static void addRow(QAbstractItemModel* model, hard_disk_t* hd) { +static void +addRow(QAbstractItemModel *model, hard_disk_t *hd) +{ const QString userPath = usr_path; int row = model->rowCount(); @@ -77,7 +81,7 @@ static void addRow(QAbstractItemModel* model, hard_disk_t* hd) { QString busName = Harddrives::BusChannelName(hd->bus, hd->channel); model->setData(model->index(row, ColumnBus), busName); - model->setData(model->index(row, ColumnBus), ProgSettings::loadIcon( "/hard_disk.ico"), Qt::DecorationRole); + model->setData(model->index(row, ColumnBus), ProgSettings::loadIcon("/hard_disk.ico"), Qt::DecorationRole); model->setData(model->index(row, ColumnBus), hd->bus, DataBus); model->setData(model->index(row, ColumnBus), hd->bus, DataBusPrevious); model->setData(model->index(row, ColumnBus), hd->channel, DataBusChannel); @@ -99,13 +103,13 @@ static void addRow(QAbstractItemModel* model, hard_disk_t* hd) { model->setData(model->index(row, ColumnSpeed), hd->speed_preset, Qt::UserRole); } -SettingsHarddisks::SettingsHarddisks(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsHarddisks) +SettingsHarddisks::SettingsHarddisks(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsHarddisks) { ui->setupUi(this); - QAbstractItemModel* model = new QStandardItemModel(0, 7, this); + QAbstractItemModel *model = new QStandardItemModel(0, 7, this); model->setHeaderData(ColumnBus, Qt::Horizontal, tr("Bus")); model->setHeaderData(ColumnFilename, Qt::Horizontal, tr("File")); model->setHeaderData(ColumnCylinders, Qt::Horizontal, tr("C")); @@ -120,15 +124,14 @@ SettingsHarddisks::SettingsHarddisks(QWidget *parent) : addRow(model, &hdd[i]); } } - if (model->rowCount() == HDD_NUM) - { + if (model->rowCount() == HDD_NUM) { ui->pushButtonNew->setEnabled(false); ui->pushButtonExisting->setEnabled(false); } ui->tableView->resizeColumnsToContents(); ui->tableView->horizontalHeader()->setSectionResizeMode(ColumnFilename, QHeaderView::Stretch); - auto* tableSelectionModel = ui->tableView->selectionModel(); + auto *tableSelectionModel = ui->tableView->selectionModel(); connect(tableSelectionModel, &QItemSelectionModel::currentRowChanged, this, &SettingsHarddisks::onTableRowChanged); onTableRowChanged(QModelIndex()); @@ -141,18 +144,20 @@ SettingsHarddisks::~SettingsHarddisks() delete ui; } -void SettingsHarddisks::save() { +void +SettingsHarddisks::save() +{ memset(hdd, 0, sizeof(hdd)); - auto* model = ui->tableView->model(); - int rows = model->rowCount(); + auto *model = ui->tableView->model(); + int rows = model->rowCount(); for (int i = 0; i < rows; ++i) { - auto idx = model->index(i, ColumnBus); - hdd[i].bus = idx.data(DataBus).toUInt(); - hdd[i].channel = idx.data(DataBusChannel).toUInt(); - hdd[i].tracks = idx.siblingAtColumn(ColumnCylinders).data().toUInt(); - hdd[i].hpc = idx.siblingAtColumn(ColumnHeads).data().toUInt(); - hdd[i].spt = idx.siblingAtColumn(ColumnSectors).data().toUInt(); + auto idx = model->index(i, ColumnBus); + hdd[i].bus = idx.data(DataBus).toUInt(); + hdd[i].channel = idx.data(DataBusChannel).toUInt(); + hdd[i].tracks = idx.siblingAtColumn(ColumnCylinders).data().toUInt(); + hdd[i].hpc = idx.siblingAtColumn(ColumnHeads).data().toUInt(); + hdd[i].spt = idx.siblingAtColumn(ColumnSectors).data().toUInt(); hdd[i].speed_preset = idx.siblingAtColumn(ColumnSpeed).data(Qt::UserRole).toUInt(); QByteArray fileName = idx.siblingAtColumn(ColumnFilename).data(Qt::UserRole).toString().toUtf8(); @@ -161,16 +166,18 @@ void SettingsHarddisks::save() { } } -void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { +void +SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) +{ if (index < 0) { return; } buschangeinprogress = true; - auto idx = ui->tableView->selectionModel()->currentIndex(); + auto idx = ui->tableView->selectionModel()->currentIndex(); if (idx.isValid()) { - auto* model = ui->tableView->model(); - auto col = idx.siblingAtColumn(ColumnBus); + auto *model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnBus); model->setData(col, ui->comboBoxBus->currentData(Qt::UserRole), DataBus); model->setData(col, busChannelName(col), Qt::DisplayRole); Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBusPrevious).toInt(), model->data(col, DataBusChannelPrevious).toInt()); @@ -181,8 +188,7 @@ void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { Harddrives::populateSpeeds(ui->comboBoxSpeed->model(), ui->comboBoxBus->currentData().toInt()); int chanIdx = 0; - switch (ui->comboBoxBus->currentData().toInt()) - { + switch (ui->comboBoxBus->currentData().toInt()) { case HDD_BUS_MFM: chanIdx = (Harddrives::busTrackClass->next_free_mfm_channel()); break; @@ -202,46 +208,53 @@ void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { } if (idx.isValid()) { - auto* model = ui->tableView->model(); - auto col = idx.siblingAtColumn(ColumnBus); + auto *model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnBus); model->setData(col, chanIdx, DataBusChannelPrevious); } ui->comboBoxChannel->setCurrentIndex(chanIdx); buschangeinprogress = false; } -void SettingsHarddisks::on_comboBoxChannel_currentIndexChanged(int index) { +void +SettingsHarddisks::on_comboBoxChannel_currentIndexChanged(int index) +{ if (index < 0) { return; } auto idx = ui->tableView->selectionModel()->currentIndex(); if (idx.isValid()) { - auto* model = ui->tableView->model(); - auto col = idx.siblingAtColumn(ColumnBus); + auto *model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnBus); model->setData(col, ui->comboBoxChannel->currentData(Qt::UserRole), DataBusChannel); model->setData(col, busChannelName(col), Qt::DisplayRole); - if (!buschangeinprogress) Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannelPrevious).toUInt()); + if (!buschangeinprogress) + Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannelPrevious).toUInt()); Harddrives::busTrackClass->device_track(1, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannel).toUInt()); model->setData(col, ui->comboBoxChannel->currentData(Qt::UserRole), DataBusChannelPrevious); } } -void SettingsHarddisks::on_comboBoxSpeed_currentIndexChanged(int index) { +void +SettingsHarddisks::on_comboBoxSpeed_currentIndexChanged(int index) +{ if (index < 0) { return; } auto idx = ui->tableView->selectionModel()->currentIndex(); if (idx.isValid()) { - auto* model = ui->tableView->model(); - auto col = idx.siblingAtColumn(ColumnSpeed); + auto *model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnSpeed); model->setData(col, ui->comboBoxSpeed->currentData(Qt::UserRole), Qt::UserRole); model->setData(col, hdd_preset_getname(ui->comboBoxSpeed->currentData(Qt::UserRole).toUInt())); } } -void SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) { +void +SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) +{ bool hidden = !current.isValid(); ui->labelBus->setHidden(hidden); ui->labelChannel->setHidden(hidden); @@ -250,78 +263,84 @@ void SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) { ui->comboBoxChannel->setHidden(hidden); ui->comboBoxSpeed->setHidden(hidden); - uint32_t bus = current.siblingAtColumn(ColumnBus).data(DataBus).toUInt(); + uint32_t bus = current.siblingAtColumn(ColumnBus).data(DataBus).toUInt(); uint32_t busChannel = current.siblingAtColumn(ColumnBus).data(DataBusChannel).toUInt(); - uint32_t speed = current.siblingAtColumn(ColumnSpeed).data(Qt::UserRole).toUInt(); + uint32_t speed = current.siblingAtColumn(ColumnSpeed).data(Qt::UserRole).toUInt(); - auto* model = ui->comboBoxBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (! match.isEmpty()) { + auto *model = ui->comboBoxBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) { ui->comboBoxBus->setCurrentIndex(match.first().row()); } model = ui->comboBoxChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, busChannel); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxChannel->setCurrentIndex(match.first().row()); } model = ui->comboBoxSpeed->model(); match = model->match(model->index(0, 0), Qt::UserRole, speed); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxSpeed->setCurrentIndex(match.first().row()); } } -static void addDriveFromDialog(Ui::SettingsHarddisks* ui, const HarddiskDialog& dlg) { +static void +addDriveFromDialog(Ui::SettingsHarddisks *ui, const HarddiskDialog &dlg) +{ QByteArray fn = dlg.fileName().toUtf8(); hard_disk_t hd; memset(&hd, 0, sizeof(hd)); - hd.bus = dlg.bus(); + hd.bus = dlg.bus(); hd.channel = dlg.channel(); - hd.tracks = dlg.cylinders(); - hd.hpc = dlg.heads(); - hd.spt = dlg.sectors(); + hd.tracks = dlg.cylinders(); + hd.hpc = dlg.heads(); + hd.spt = dlg.sectors(); strncpy(hd.fn, fn.data(), sizeof(hd.fn) - 1); hd.speed_preset = dlg.speed(); addRow(ui->tableView->model(), &hd); ui->tableView->resizeColumnsToContents(); ui->tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); - if (ui->tableView->model()->rowCount() == HDD_NUM) - { + if (ui->tableView->model()->rowCount() == HDD_NUM) { ui->pushButtonNew->setEnabled(false); ui->pushButtonExisting->setEnabled(false); } } -void SettingsHarddisks::on_pushButtonNew_clicked() { +void +SettingsHarddisks::on_pushButtonNew_clicked() +{ HarddiskDialog dialog(false, this); switch (dialog.exec()) { - case QDialog::Accepted: - addDriveFromDialog(ui, dialog); - break; + case QDialog::Accepted: + addDriveFromDialog(ui, dialog); + break; } } - -void SettingsHarddisks::on_pushButtonExisting_clicked() { +void +SettingsHarddisks::on_pushButtonExisting_clicked() +{ HarddiskDialog dialog(true, this); switch (dialog.exec()) { - case QDialog::Accepted: - addDriveFromDialog(ui, dialog); - break; + case QDialog::Accepted: + addDriveFromDialog(ui, dialog); + break; } } -void SettingsHarddisks::on_pushButtonRemove_clicked() { +void +SettingsHarddisks::on_pushButtonRemove_clicked() +{ auto idx = ui->tableView->selectionModel()->currentIndex(); - if (! idx.isValid()) { + if (!idx.isValid()) { return; } - auto* model = ui->tableView->model(); + auto *model = ui->tableView->model(); model->removeRow(idx.row()); ui->pushButtonNew->setEnabled(true); ui->pushButtonExisting->setEnabled(true); diff --git a/src/qt/qt_settingsharddisks.hpp b/src/qt/qt_settingsharddisks.hpp index a8aebb0bd..68d7ca3d6 100644 --- a/src/qt/qt_settingsharddisks.hpp +++ b/src/qt/qt_settingsharddisks.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsHarddisks; } -class SettingsHarddisks : public QWidget -{ +class SettingsHarddisks : public QWidget { Q_OBJECT public: @@ -27,11 +26,11 @@ private slots: void on_pushButtonNew_clicked(); void on_comboBoxBus_currentIndexChanged(int index); - void onTableRowChanged(const QModelIndex& current); + void onTableRowChanged(const QModelIndex ¤t); private: Ui::SettingsHarddisks *ui; - bool buschangeinprogress = false; + bool buschangeinprogress = false; }; #endif // QT_SETTINGSHARDDISKS_HPP diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index d5a62534f..49d84037f 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -31,9 +31,9 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_joystickconfiguration.hpp" -SettingsInput::SettingsInput(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsInput) +SettingsInput::SettingsInput(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsInput) { ui->setupUi(this); @@ -45,21 +45,25 @@ SettingsInput::~SettingsInput() delete ui; } -void SettingsInput::save() { - mouse_type = ui->comboBoxMouse->currentData().toInt(); +void +SettingsInput::save() +{ + mouse_type = ui->comboBoxMouse->currentData().toInt(); joystick_type = ui->comboBoxJoystick->currentData().toInt(); } -void SettingsInput::onCurrentMachineChanged(int machineId) { +void +SettingsInput::onCurrentMachineChanged(int machineId) +{ // win_settings_video_proc, WM_INITDIALOG this->machineId = machineId; - auto* mouseModel = ui->comboBoxMouse->model(); - auto removeRows = mouseModel->rowCount(); + auto *mouseModel = ui->comboBoxMouse->model(); + auto removeRows = mouseModel->rowCount(); int selectedRow = 0; for (int i = 0; i < mouse_get_ndev(); ++i) { - const auto* dev = mouse_get_device(i); + const auto *dev = mouse_get_device(i); if ((i == MOUSE_TYPE_INTERNAL) && (machine_has_flags(machineId, MACHINE_MOUSE) == 0)) { continue; } @@ -69,7 +73,7 @@ void SettingsInput::onCurrentMachineChanged(int machineId) { } QString name = DeviceConfig::DeviceName(dev, mouse_get_internal_name(i), 0); - int row = mouseModel->rowCount(); + int row = mouseModel->rowCount(); mouseModel->insertRow(row); auto idx = mouseModel->index(row, 0); @@ -83,12 +87,11 @@ void SettingsInput::onCurrentMachineChanged(int machineId) { mouseModel->removeRows(0, removeRows); ui->comboBoxMouse->setCurrentIndex(selectedRow); - - int i = 0; - char* joyName = joystick_get_name(i); - auto* joystickModel = ui->comboBoxJoystick->model(); - removeRows = joystickModel->rowCount(); - selectedRow = 0; + int i = 0; + char *joyName = joystick_get_name(i); + auto *joystickModel = ui->comboBoxJoystick->model(); + removeRows = joystickModel->rowCount(); + selectedRow = 0; while (joyName) { int row = Models::AddEntry(joystickModel, tr(joyName).toUtf8().data(), i); if (i == joystick_type) { @@ -102,16 +105,19 @@ void SettingsInput::onCurrentMachineChanged(int machineId) { ui->comboBoxJoystick->setCurrentIndex(selectedRow); } -void SettingsInput::on_comboBoxMouse_currentIndexChanged(int index) { +void +SettingsInput::on_comboBoxMouse_currentIndexChanged(int index) +{ int mouseId = ui->comboBoxMouse->currentData().toInt(); ui->pushButtonConfigureMouse->setEnabled(mouse_has_config(mouseId) > 0); } - -void SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) { +void +SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) +{ int joystickId = ui->comboBoxJoystick->currentData().toInt(); for (int i = 0; i < 4; ++i) { - auto* btn = findChild(QString("pushButtonJoystick%1").arg(i+1)); + auto *btn = findChild(QString("pushButtonJoystick%1").arg(i + 1)); if (btn == nullptr) { continue; } @@ -119,15 +125,19 @@ void SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) { } } -void SettingsInput::on_pushButtonConfigureMouse_clicked() { +void +SettingsInput::on_pushButtonConfigureMouse_clicked() +{ int mouseId = ui->comboBoxMouse->currentData().toInt(); - DeviceConfig::ConfigureDevice(mouse_get_device(mouseId), 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(mouse_get_device(mouseId), 0, qobject_cast(Settings::settings)); } -static int get_axis(JoystickConfiguration& jc, int axis, int joystick_nr) { +static int +get_axis(JoystickConfiguration &jc, int axis, int joystick_nr) +{ int axis_sel = jc.selectedAxis(axis); - int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; + int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; + int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; if (axis_sel < nr_axes) { return axis_sel; @@ -145,12 +155,13 @@ static int get_axis(JoystickConfiguration& jc, int axis, int joystick_nr) { return SLIDER | (axis_sel >> 1); } -static int get_pov(JoystickConfiguration& jc, int pov, int joystick_nr) { +static int +get_pov(JoystickConfiguration &jc, int pov, int joystick_nr) +{ int pov_sel = jc.selectedPov(pov); - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2; + int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs * 2; - if (pov_sel < nr_povs) - { + if (pov_sel < nr_povs) { if (pov_sel & 1) return POV_Y | (pov_sel >> 1); else @@ -160,13 +171,15 @@ static int get_pov(JoystickConfiguration& jc, int pov, int joystick_nr) { return pov_sel - nr_povs; } -static void updateJoystickConfig(int type, int joystick_nr, QWidget* parent) { +static void +updateJoystickConfig(int type, int joystick_nr, QWidget *parent) +{ JoystickConfiguration jc(type, joystick_nr, parent); switch (jc.exec()) { - case QDialog::Rejected: - return; - case QDialog::Accepted: - break; + case QDialog::Rejected: + return; + case QDialog::Accepted: + break; } joystick_state[joystick_nr].plat_joystick_nr = jc.selectedDevice(); @@ -184,18 +197,26 @@ static void updateJoystickConfig(int type, int joystick_nr, QWidget* parent) { } } -void SettingsInput::on_pushButtonJoystick1_clicked() { +void +SettingsInput::on_pushButtonJoystick1_clicked() +{ updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 0, this); } -void SettingsInput::on_pushButtonJoystick2_clicked() { +void +SettingsInput::on_pushButtonJoystick2_clicked() +{ updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 1, this); } -void SettingsInput::on_pushButtonJoystick3_clicked() { +void +SettingsInput::on_pushButtonJoystick3_clicked() +{ updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 2, this); } -void SettingsInput::on_pushButtonJoystick4_clicked() { +void +SettingsInput::on_pushButtonJoystick4_clicked() +{ updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 3, this); } diff --git a/src/qt/qt_settingsinput.hpp b/src/qt/qt_settingsinput.hpp index f9e44740d..0b8b665aa 100644 --- a/src/qt/qt_settingsinput.hpp +++ b/src/qt/qt_settingsinput.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsInput; } -class SettingsInput : public QWidget -{ +class SettingsInput : public QWidget { Q_OBJECT public: @@ -31,7 +30,7 @@ private slots: private: Ui::SettingsInput *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSINPUT_HPP diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index 56456000b..0d2ffa129 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -35,45 +35,45 @@ extern "C" { } // from nvr.h, which we can't import into CPP code -#define TIME_SYNC_DISABLED 0 -#define TIME_SYNC_ENABLED 1 -#define TIME_SYNC_UTC 2 +#define TIME_SYNC_DISABLED 0 +#define TIME_SYNC_ENABLED 1 +#define TIME_SYNC_UTC 2 #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsMachine::SettingsMachine(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsMachine) +SettingsMachine::SettingsMachine(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsMachine) { ui->setupUi(this); switch (time_sync) { - case TIME_SYNC_ENABLED: - ui->radioButtonLocalTime->setChecked(true); - break; - case TIME_SYNC_ENABLED | TIME_SYNC_UTC: - ui->radioButtonUTC->setChecked(true); - break; - case TIME_SYNC_DISABLED: - default: - ui->radioButtonDisabled->setChecked(true); - break; + case TIME_SYNC_ENABLED: + ui->radioButtonLocalTime->setChecked(true); + break; + case TIME_SYNC_ENABLED | TIME_SYNC_UTC: + ui->radioButtonUTC->setChecked(true); + break; + case TIME_SYNC_DISABLED: + default: + ui->radioButtonDisabled->setChecked(true); + break; } - auto* waitStatesModel = ui->comboBoxWaitStates->model(); + auto *waitStatesModel = ui->comboBoxWaitStates->model(); waitStatesModel->insertRows(0, 9); auto idx = waitStatesModel->index(0, 0); waitStatesModel->setData(idx, tr("Default"), Qt::DisplayRole); waitStatesModel->setData(idx, 0, Qt::UserRole); for (int i = 0; i < 8; ++i) { - idx = waitStatesModel->index(i+1, 0); + idx = waitStatesModel->index(i + 1, 0); waitStatesModel->setData(idx, QString::asprintf(tr("%i Wait state(s)").toUtf8().constData(), i), Qt::DisplayRole); - waitStatesModel->setData(idx, i+1, Qt::UserRole); + waitStatesModel->setData(idx, i + 1, Qt::UserRole); } - int selectedMachineType = 0; - auto* machineTypesModel = ui->comboBoxMachineType->model(); + int selectedMachineType = 0; + auto *machineTypesModel = ui->comboBoxMachineType->model(); for (int i = 1; i < MACHINE_TYPE_MAX; ++i) { int j = 0; while (machine_get_internal_name_ex(j) != nullptr) { @@ -92,15 +92,18 @@ SettingsMachine::SettingsMachine(QWidget *parent) : ui->comboBoxMachineType->setCurrentIndex(selectedMachineType); } -SettingsMachine::~SettingsMachine() { +SettingsMachine::~SettingsMachine() +{ delete ui; } -void SettingsMachine::save() { - machine = ui->comboBoxMachine->currentData().toInt(); - cpu_f = const_cast(&cpu_families[ui->comboBoxCPU->currentData().toInt()]); - cpu = ui->comboBoxSpeed->currentData().toInt(); - fpu_type = ui->comboBoxFPU->currentData().toInt(); +void +SettingsMachine::save() +{ + machine = ui->comboBoxMachine->currentData().toInt(); + cpu_f = const_cast(&cpu_families[ui->comboBoxCPU->currentData().toInt()]); + cpu = ui->comboBoxSpeed->currentData().toInt(); + fpu_type = ui->comboBoxFPU->currentData().toInt(); cpu_use_dynarec = ui->checkBoxDynamicRecompiler->isChecked() ? 1 : 0; int64_t temp_mem_size; if (machine_get_ram_granularity(machine) < 1024) { @@ -132,13 +135,15 @@ void SettingsMachine::save() { } } -void SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index) { +void +SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index) +{ if (index < 0) { return; } - auto* model = ui->comboBoxMachine->model(); - int removeRows = model->rowCount(); + auto *model = ui->comboBoxMachine->model(); + int removeRows = model->rowCount(); int selectedMachineRow = 0; for (int i = 0; i < machine_count(); ++i) { @@ -155,22 +160,23 @@ void SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index) { ui->comboBoxMachine->setCurrentIndex(selectedMachineRow); } - -void SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index) { +void +SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index) +{ // win_settings_machine_recalc_machine if (index < 0) { return; } - int machineId = ui->comboBoxMachine->currentData().toInt(); - const auto* device = machine_getdevice(machineId); + int machineId = ui->comboBoxMachine->currentData().toInt(); + const auto *device = machine_getdevice(machineId); ui->pushButtonConfigure->setEnabled((device != nullptr) && (device->config != nullptr)); - auto* modelCpu = ui->comboBoxCPU->model(); - int removeRows = modelCpu->rowCount(); + auto *modelCpu = ui->comboBoxCPU->model(); + int removeRows = modelCpu->rowCount(); - int i = 0; - int eligibleRows = 0; + int i = 0; + int eligibleRows = 0; int selectedCpuFamilyRow = 0; while (cpu_families[i].package != 0) { if (cpu_family_is_eligible(&cpu_families[i], machineId)) { @@ -204,22 +210,23 @@ void SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index) { emit currentMachineChanged(machineId); } - -void SettingsMachine::on_comboBoxCPU_currentIndexChanged(int index) { +void +SettingsMachine::on_comboBoxCPU_currentIndexChanged(int index) +{ if (index < 0) { return; } - int machineId = ui->comboBoxMachine->currentData().toInt(); - int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); - const auto* cpuFamily = &cpu_families[cpuFamilyId]; + int machineId = ui->comboBoxMachine->currentData().toInt(); + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto *cpuFamily = &cpu_families[cpuFamilyId]; - auto* modelSpeed = ui->comboBoxSpeed->model(); - int removeRows = modelSpeed->rowCount(); + auto *modelSpeed = ui->comboBoxSpeed->model(); + int removeRows = modelSpeed->rowCount(); // win_settings_machine_recalc_cpu_m - int i = 0; - int eligibleRows = 0; + int i = 0; + int eligibleRows = 0; int selectedSpeedRow = 0; while (cpuFamily->cpus[i].cpu_type != 0) { if (cpu_is_eligible(cpuFamily, i, machineId)) { @@ -237,17 +244,18 @@ void SettingsMachine::on_comboBoxCPU_currentIndexChanged(int index) { ui->comboBoxSpeed->setCurrentIndex(selectedSpeedRow); } - -void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { +void +SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) +{ if (index < 0) { return; } // win_settings_machine_recalc_cpu - int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); - const auto* cpuFamily = &cpu_families[cpuFamilyId]; - int cpuId = ui->comboBoxSpeed->currentData().toInt(); - uint cpuType = cpuFamily->cpus[cpuId].cpu_type; + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto *cpuFamily = &cpu_families[cpuFamilyId]; + int cpuId = ui->comboBoxSpeed->currentData().toInt(); + uint cpuType = cpuFamily->cpus[cpuId].cpu_type; if ((cpuType >= CPU_286) && (cpuType <= CPU_386DX)) { ui->comboBoxWaitStates->setEnabled(true); @@ -259,7 +267,7 @@ void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { #ifdef USE_DYNAREC uint8_t flags = cpuFamily->cpus[cpuId].cpu_flags; - if (! (flags & CPU_SUPPORTS_DYNAREC)) { + if (!(flags & CPU_SUPPORTS_DYNAREC)) { ui->checkBoxDynamicRecompiler->setChecked(false); ui->checkBoxDynamicRecompiler->setEnabled(false); } else if (flags & CPU_REQUIRES_DYNAREC) { @@ -272,12 +280,12 @@ void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { #endif // win_settings_machine_recalc_fpu - auto* modelFpu = ui->comboBoxFPU->model(); - int removeRows = modelFpu->rowCount(); + auto *modelFpu = ui->comboBoxFPU->model(); + int removeRows = modelFpu->rowCount(); - int i = 0; + int i = 0; int selectedFpuRow = 0; - for (const char* fpuName = fpu_get_name_from_index(cpuFamily, cpuId, i); fpuName != nullptr; fpuName = fpu_get_name_from_index(cpuFamily, cpuId, ++i)) { + for (const char *fpuName = fpu_get_name_from_index(cpuFamily, cpuId, i); fpuName != nullptr; fpuName = fpu_get_name_from_index(cpuFamily, cpuId, ++i)) { auto fpuType = fpu_get_type_from_index(cpuFamily, cpuId, i); Models::AddEntry(modelFpu, QString("%1").arg(fpuName), fpuType); if (fpu_type == fpuType) { @@ -291,9 +299,11 @@ void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { ui->comboBoxFPU->setCurrentIndex(selectedFpuRow); } -void SettingsMachine::on_pushButtonConfigure_clicked() { +void +SettingsMachine::on_pushButtonConfigure_clicked() +{ // deviceconfig_inst_open - int machineId = ui->comboBoxMachine->currentData().toInt(); - const auto* device = machine_getdevice(machineId); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + int machineId = ui->comboBoxMachine->currentData().toInt(); + const auto *device = machine_getdevice(machineId); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingsmachine.hpp b/src/qt/qt_settingsmachine.hpp index d0d4aabd2..abb4f3014 100644 --- a/src/qt/qt_settingsmachine.hpp +++ b/src/qt/qt_settingsmachine.hpp @@ -7,18 +7,17 @@ namespace Ui { class SettingsMachine; } -class SettingsMachine : public QWidget -{ +class SettingsMachine : public QWidget { Q_OBJECT public: - explicit SettingsMachine(QWidget *parent = nullptr); + explicit SettingsMachine(QWidget *parent = nullptr); ~SettingsMachine(); - void save(); + void save(); signals: - void currentMachineChanged(int machineId); + void currentMachineChanged(int machineId); private slots: void on_pushButtonConfigure_clicked(); @@ -32,7 +31,7 @@ private slots: void on_comboBoxMachine_currentIndexChanged(int index); private slots: - void on_comboBoxMachineType_currentIndexChanged(int index); + void on_comboBoxMachineType_currentIndexChanged(int index); private: Ui::SettingsMachine *ui; diff --git a/src/qt/qt_settingsnetwork.cpp b/src/qt/qt_settingsnetwork.cpp index 1cb42cc22..cbddfab72 100644 --- a/src/qt/qt_settingsnetwork.cpp +++ b/src/qt/qt_settingsnetwork.cpp @@ -29,16 +29,17 @@ extern "C" { #include "qt_models_common.hpp" #include "qt_deviceconfig.hpp" -void SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) { +void +SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) +{ for (int i = 0; i < NET_CARD_MAX; ++i) { - auto* nic_cbox = findChild(QString("comboBoxNIC%1").arg(i+1)); - auto* net_type_cbox = findChild(QString("comboBoxNet%1").arg(i+1)); - auto* intf_cbox = findChild(QString("comboBoxIntf%1").arg(i+1)); - auto* conf_btn = findChild(QString("pushButtonConf%1").arg(i+1)); + auto *nic_cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); + auto *net_type_cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); + auto *intf_cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); + auto *conf_btn = findChild(QString("pushButtonConf%1").arg(i + 1)); - int netType = net_type_cbox->currentData().toInt(); - bool adaptersEnabled = netType == NET_TYPE_SLIRP || - (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0); + int netType = net_type_cbox->currentData().toInt(); + bool adaptersEnabled = netType == NET_TYPE_SLIRP || (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0); intf_cbox->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_PCAP); nic_cbox->setEnabled(adaptersEnabled); @@ -46,18 +47,18 @@ void SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) { } } -SettingsNetwork::SettingsNetwork(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsNetwork) +SettingsNetwork::SettingsNetwork(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsNetwork) { ui->setupUi(this); onCurrentMachineChanged(machine); enableElements(ui); for (int i = 0; i < NET_CARD_MAX; i++) { - auto* nic_cbox = findChild(QString("comboBoxNIC%1").arg(i+1)); - auto* net_type_cbox = findChild(QString("comboBoxNet%1").arg(i+1)); - auto* intf_cbox = findChild(QString("comboBoxIntf%1").arg(i+1)); + auto *nic_cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); + auto *net_type_cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); + auto *intf_cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); connect(nic_cbox, QOverload::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged); connect(net_type_cbox, QOverload::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged); connect(intf_cbox, QOverload::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged); @@ -69,30 +70,34 @@ SettingsNetwork::~SettingsNetwork() delete ui; } -void SettingsNetwork::save() { +void +SettingsNetwork::save() +{ for (int i = 0; i < NET_CARD_MAX; ++i) { - auto* cbox = findChild(QString("comboBoxNIC%1").arg(i+1)); + auto *cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); net_cards_conf[i].device_num = cbox->currentData().toInt(); - cbox = findChild(QString("comboBoxNet%1").arg(i+1)); - net_cards_conf[i].net_type = cbox->currentData().toInt(); - cbox = findChild(QString("comboBoxIntf%1").arg(i+1)); + cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); + net_cards_conf[i].net_type = cbox->currentData().toInt(); + cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); memset(net_cards_conf[i].host_dev_name, '\0', sizeof(net_cards_conf[i].host_dev_name)); strncpy(net_cards_conf[i].host_dev_name, network_devs[cbox->currentData().toInt()].device, sizeof(net_cards_conf[i].host_dev_name) - 1); } } -void SettingsNetwork::onCurrentMachineChanged(int machineId) { +void +SettingsNetwork::onCurrentMachineChanged(int machineId) +{ this->machineId = machineId; - int c = 0; + int c = 0; int selectedRow = 0; for (int i = 0; i < NET_CARD_MAX; ++i) { - auto* cbox = findChild(QString("comboBoxNIC%1").arg(i+1)); - auto *model = cbox->model(); - auto removeRows = model->rowCount(); - c = 0; - selectedRow = 0; + auto *cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); + auto *model = cbox->model(); + auto removeRows = model->rowCount(); + c = 0; + selectedRow = 0; while (true) { auto name = DeviceConfig::DeviceName(network_card_getdevice(c), network_card_get_internal_name(c), 1); @@ -114,8 +119,8 @@ void SettingsNetwork::onCurrentMachineChanged(int machineId) { cbox->setCurrentIndex(-1); cbox->setCurrentIndex(selectedRow); - cbox = findChild(QString("comboBoxNet%1").arg(i+1)); - model = cbox->model(); + cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); + model = cbox->model(); removeRows = model->rowCount(); Models::AddEntry(model, tr("None"), NET_TYPE_NONE); Models::AddEntry(model, "SLiRP", NET_TYPE_SLIRP); @@ -128,9 +133,9 @@ void SettingsNetwork::onCurrentMachineChanged(int machineId) { selectedRow = 0; QString currentPcapDevice = net_cards_conf[i].host_dev_name; - cbox = findChild(QString("comboBoxIntf%1").arg(i+1)); - model = cbox->model(); - removeRows = model->rowCount(); + cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); + model = cbox->model(); + removeRows = model->rowCount(); for (int c = 0; c < network_ndev; c++) { Models::AddEntry(model, tr(network_devs[c].description), c); if (QString(network_devs[c].device) == currentPcapDevice) { @@ -142,7 +147,9 @@ void SettingsNetwork::onCurrentMachineChanged(int machineId) { } } -void SettingsNetwork::on_comboIndexChanged(int index) { +void +SettingsNetwork::on_comboIndexChanged(int index) +{ if (index < 0) { return; } @@ -150,18 +157,26 @@ void SettingsNetwork::on_comboIndexChanged(int index) { enableElements(ui); } -void SettingsNetwork::on_pushButtonConf1_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC1->currentData().toInt()), 1, qobject_cast(Settings::settings)); +void +SettingsNetwork::on_pushButtonConf1_clicked() +{ + DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC1->currentData().toInt()), 1, qobject_cast(Settings::settings)); } -void SettingsNetwork::on_pushButtonConf2_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC2->currentData().toInt()), 2, qobject_cast(Settings::settings)); +void +SettingsNetwork::on_pushButtonConf2_clicked() +{ + DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC2->currentData().toInt()), 2, qobject_cast(Settings::settings)); } -void SettingsNetwork::on_pushButtonConf3_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC3->currentData().toInt()), 3, qobject_cast(Settings::settings)); +void +SettingsNetwork::on_pushButtonConf3_clicked() +{ + DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC3->currentData().toInt()), 3, qobject_cast(Settings::settings)); } -void SettingsNetwork::on_pushButtonConf4_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC4->currentData().toInt()), 4, qobject_cast(Settings::settings)); +void +SettingsNetwork::on_pushButtonConf4_clicked() +{ + DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingsnetwork.hpp b/src/qt/qt_settingsnetwork.hpp index 55d983b5f..d39d90896 100644 --- a/src/qt/qt_settingsnetwork.hpp +++ b/src/qt/qt_settingsnetwork.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsNetwork; } -class SettingsNetwork : public QWidget -{ +class SettingsNetwork : public QWidget { Q_OBJECT public: @@ -31,7 +30,7 @@ private slots: private: Ui::SettingsNetwork *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSNETWORK_HPP diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index ebf849d28..edffd360a 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -28,15 +28,16 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsOtherPeripherals::SettingsOtherPeripherals(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsOtherPeripherals) +SettingsOtherPeripherals::SettingsOtherPeripherals(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsOtherPeripherals) { ui->setupUi(this); onCurrentMachineChanged(machine); } -void SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) +void +SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) { this->machineId = machineId; @@ -52,9 +53,9 @@ void SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) ui->comboBoxCard4->clear(); ui->comboBoxRTC->clear(); - auto* model = ui->comboBoxRTC->model(); - int d = 0; - int selectedRow = 0; + auto *model = ui->comboBoxRTC->model(); + int d = 0; + int selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(isartc_get_device(d), isartc_get_internal_name(d), 0); if (name.isEmpty()) { @@ -74,9 +75,9 @@ void SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) ui->comboBoxRTC->setCurrentIndex(selectedRow); for (int c = 0; c < ISAMEM_MAX; c++) { - auto* cbox = findChild(QString("comboBoxCard%1").arg(c + 1)); - model = cbox->model(); - d = 0; + auto *cbox = findChild(QString("comboBoxCard%1").arg(c + 1)); + model = cbox->model(); + d = 0; selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(isamem_get_device(d), isamem_get_internal_name(d), 0); @@ -97,7 +98,7 @@ void SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) cbox->setCurrentIndex(-1); cbox->setCurrentIndex(selectedRow); cbox->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); - findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled(isamem_type[c] != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); + findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled(isamem_type[c] != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } } @@ -106,70 +107,92 @@ SettingsOtherPeripherals::~SettingsOtherPeripherals() delete ui; } -void SettingsOtherPeripherals::save() { +void +SettingsOtherPeripherals::save() +{ /* Other peripherals category */ - bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; + bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; - isartc_type = ui->comboBoxRTC->currentData().toInt(); + isartc_type = ui->comboBoxRTC->currentData().toInt(); /* ISA memory boards. */ for (int i = 0; i < ISAMEM_MAX; i++) { - auto* cbox = findChild(QString("comboBoxCard%1").arg(i + 1)); + auto *cbox = findChild(QString("comboBoxCard%1").arg(i + 1)); isamem_type[i] = cbox->currentData().toInt(); } } -void SettingsOtherPeripherals::on_comboBoxRTC_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxRTC_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureRTC->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureRTC_clicked() { - DeviceConfig::ConfigureDevice(isartc_get_device(ui->comboBoxRTC->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureRTC_clicked() +{ + DeviceConfig::ConfigureDevice(isartc_get_device(ui->comboBoxRTC->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsOtherPeripherals::on_comboBoxCard1_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxCard1_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureCard1->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureCard1_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard1->currentData().toInt()), 1, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureCard1_clicked() +{ + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard1->currentData().toInt()), 1, qobject_cast(Settings::settings)); } -void SettingsOtherPeripherals::on_comboBoxCard2_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxCard2_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureCard2->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureCard2_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard2->currentData().toInt()), 2, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureCard2_clicked() +{ + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard2->currentData().toInt()), 2, qobject_cast(Settings::settings)); } -void SettingsOtherPeripherals::on_comboBoxCard3_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxCard3_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureCard3->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureCard3_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard3->currentData().toInt()), 3, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureCard3_clicked() +{ + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard3->currentData().toInt()), 3, qobject_cast(Settings::settings)); } -void SettingsOtherPeripherals::on_comboBoxCard4_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxCard4_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureCard4->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureCard4_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard4->currentData().toInt()), 4, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureCard4_clicked() +{ + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingsotherperipherals.hpp b/src/qt/qt_settingsotherperipherals.hpp index f8eed2c9e..97e47c90e 100644 --- a/src/qt/qt_settingsotherperipherals.hpp +++ b/src/qt/qt_settingsotherperipherals.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsOtherPeripherals; } -class SettingsOtherPeripherals : public QWidget -{ +class SettingsOtherPeripherals : public QWidget { Q_OBJECT public: @@ -34,7 +33,7 @@ private slots: private: Ui::SettingsOtherPeripherals *ui; - int machineId{0}; + int machineId { 0 }; }; #endif // QT_SETTINGSOTHERPERIPHERALS_HPP diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index 574fdccb5..f625388ea 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -33,20 +33,24 @@ extern "C" { #include "qt_settings_bus_tracking.hpp" #include "qt_progsettings.hpp" -static QString moDriveTypeName(int i) { +static QString +moDriveTypeName(int i) +{ return QString("%1 %2 %3").arg(mo_drive_types[i].vendor, mo_drive_types[i].model, mo_drive_types[i].revision); } -static void setMOBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t bus, uint8_t channel) { +static void +setMOBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) +{ QIcon icon; switch (bus) { - case MO_BUS_DISABLED: - icon = ProgSettings::loadIcon("/mo_disabled.ico"); - break; - case MO_BUS_ATAPI: - case MO_BUS_SCSI: - icon = ProgSettings::loadIcon("/mo.ico"); - break; + case MO_BUS_DISABLED: + icon = ProgSettings::loadIcon("/mo_disabled.ico"); + break; + case MO_BUS_ATAPI: + case MO_BUS_SCSI: + icon = ProgSettings::loadIcon("/mo.ico"); + break; } auto i = idx.siblingAtColumn(0); @@ -56,7 +60,9 @@ static void setMOBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t model->setData(i, icon, Qt::DecorationRole); } -static void setMOType(QAbstractItemModel* model, const QModelIndex& idx, uint32_t type) { +static void +setMOType(QAbstractItemModel *model, const QModelIndex &idx, uint32_t type) +{ auto i = idx.siblingAtColumn(1); if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == MO_BUS_DISABLED) { model->setData(i, QCoreApplication::translate("", "None")); @@ -66,16 +72,18 @@ static void setMOType(QAbstractItemModel* model, const QModelIndex& idx, uint32_ model->setData(i, type, Qt::UserRole); } -static void setZIPBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t bus, uint8_t channel) { +static void +setZIPBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) +{ QIcon icon; switch (bus) { - case ZIP_BUS_DISABLED: - icon = ProgSettings::loadIcon("/zip_disabled.ico"); - break; - case ZIP_BUS_ATAPI: - case ZIP_BUS_SCSI: - icon = ProgSettings::loadIcon("/zip.ico"); - break; + case ZIP_BUS_DISABLED: + icon = ProgSettings::loadIcon("/zip_disabled.ico"); + break; + case ZIP_BUS_ATAPI: + case ZIP_BUS_SCSI: + icon = ProgSettings::loadIcon("/zip.ico"); + break; } auto i = idx.siblingAtColumn(0); @@ -85,20 +93,22 @@ static void setZIPBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t model->setData(i, icon, Qt::DecorationRole); } -static void setZIPType(QAbstractItemModel* model, const QModelIndex& idx, bool is250) { +static void +setZIPType(QAbstractItemModel *model, const QModelIndex &idx, bool is250) +{ auto i = idx.siblingAtColumn(1); model->setData(i, is250 ? "ZIP 250" : "ZIP 100"); model->setData(i, is250, Qt::UserRole); } -SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsOtherRemovable) +SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsOtherRemovable) { ui->setupUi(this); Harddrives::populateRemovableBuses(ui->comboBoxMOBus->model()); - auto* model = ui->comboBoxMOType->model(); + auto *model = ui->comboBoxMOType->model(); for (uint32_t i = 0; i < KNOWN_MO_DRIVE_TYPES; i++) { Models::AddEntry(model, moDriveTypeName(i), i); } @@ -120,9 +130,6 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) : connect(ui->tableViewMO->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsOtherRemovable::onMORowChanged); ui->tableViewMO->setCurrentIndex(model->index(0, 0)); - - - Harddrives::populateRemovableBuses(ui->comboBoxZIPBus->model()); model = new QStandardItemModel(0, 2, this); @@ -148,79 +155,89 @@ SettingsOtherRemovable::~SettingsOtherRemovable() delete ui; } -void SettingsOtherRemovable::save() { - auto* model = ui->tableViewMO->model(); +void +SettingsOtherRemovable::save() +{ + auto *model = ui->tableViewMO->model(); for (int i = 0; i < MO_NUM; i++) { - mo_drives[i].f = NULL; - mo_drives[i].priv = NULL; + mo_drives[i].f = NULL; + mo_drives[i].priv = NULL; mo_drives[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); - mo_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); - mo_drives[i].type = model->index(i, 1).data(Qt::UserRole).toUInt(); + mo_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + mo_drives[i].type = model->index(i, 1).data(Qt::UserRole).toUInt(); } model = ui->tableViewZIP->model(); for (int i = 0; i < ZIP_NUM; i++) { - zip_drives[i].f = NULL; - zip_drives[i].priv = NULL; + zip_drives[i].f = NULL; + zip_drives[i].priv = NULL; zip_drives[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); - zip_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); - zip_drives[i].is_250 = model->index(i, 1).data(Qt::UserRole).toBool() ? 1 : 0; + zip_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + zip_drives[i].is_250 = model->index(i, 1).data(Qt::UserRole).toBool() ? 1 : 0; } } -void SettingsOtherRemovable::onMORowChanged(const QModelIndex ¤t) { - uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); +void +SettingsOtherRemovable::onMORowChanged(const QModelIndex ¤t) +{ + uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); - uint8_t type = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); + uint8_t type = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); ui->comboBoxMOBus->setCurrentIndex(-1); - auto* model = ui->comboBoxMOBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (! match.isEmpty()) { + auto *model = ui->comboBoxMOBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) { ui->comboBoxMOBus->setCurrentIndex(match.first().row()); } model = ui->comboBoxMOChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxMOChannel->setCurrentIndex(match.first().row()); } ui->comboBoxMOType->setCurrentIndex(type); } -void SettingsOtherRemovable::onZIPRowChanged(const QModelIndex ¤t) { - uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); +void +SettingsOtherRemovable::onZIPRowChanged(const QModelIndex ¤t) +{ + uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); - bool is250 = current.siblingAtColumn(1).data(Qt::UserRole).toBool(); + bool is250 = current.siblingAtColumn(1).data(Qt::UserRole).toBool(); ui->comboBoxZIPBus->setCurrentIndex(-1); - auto* model = ui->comboBoxZIPBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (! match.isEmpty()) { + auto *model = ui->comboBoxZIPBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) { ui->comboBoxZIPBus->setCurrentIndex(match.first().row()); } model = ui->comboBoxZIPChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxZIPChannel->setCurrentIndex(match.first().row()); } ui->checkBoxZIP250->setChecked(is250); } -void SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) { +void +SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) +{ if (index < 0) { return; } - int bus = ui->comboBoxMOBus->currentData().toInt(); + int bus = ui->comboBoxMOBus->currentData().toInt(); bool enabled = (bus != MO_BUS_DISABLED); ui->comboBoxMOChannel->setEnabled(enabled); ui->comboBoxMOType->setEnabled(enabled); Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), bus); } -void SettingsOtherRemovable::on_comboBoxMOBus_activated(int) { +void +SettingsOtherRemovable::on_comboBoxMOBus_activated(int) +{ auto i = ui->tableViewMO->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); ui->comboBoxMOChannel->setCurrentIndex(ui->comboBoxMOBus->currentData().toUInt() == MO_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); @@ -239,7 +256,9 @@ void SettingsOtherRemovable::on_comboBoxMOBus_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) { +void +SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) +{ auto i = ui->tableViewMO->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); setMOBus( @@ -250,7 +269,9 @@ void SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsOtherRemovable::on_comboBoxMOType_activated(int) { +void +SettingsOtherRemovable::on_comboBoxMOType_activated(int) +{ setMOType( ui->tableViewMO->model(), ui->tableViewMO->selectionModel()->currentIndex(), @@ -259,19 +280,23 @@ void SettingsOtherRemovable::on_comboBoxMOType_activated(int) { ui->tableViewMO->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); } -void SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) { +void +SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) +{ if (index < 0) { return; } - int bus = ui->comboBoxZIPBus->currentData().toInt(); + int bus = ui->comboBoxZIPBus->currentData().toInt(); bool enabled = (bus != ZIP_BUS_DISABLED); ui->comboBoxZIPChannel->setEnabled(enabled); ui->checkBoxZIP250->setEnabled(enabled); Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), bus); } -void SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) { +void +SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) +{ auto i = ui->tableViewZIP->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); ui->comboBoxZIPChannel->setCurrentIndex(ui->comboBoxZIPBus->currentData().toUInt() == ZIP_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); @@ -283,7 +308,9 @@ void SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) { +void +SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) +{ auto i = ui->tableViewZIP->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); setZIPBus( @@ -294,7 +321,9 @@ void SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsOtherRemovable::on_checkBoxZIP250_stateChanged(int state) { +void +SettingsOtherRemovable::on_checkBoxZIP250_stateChanged(int state) +{ setZIPType( ui->tableViewZIP->model(), ui->tableViewZIP->selectionModel()->currentIndex(), diff --git a/src/qt/qt_settingsotherremovable.hpp b/src/qt/qt_settingsotherremovable.hpp index c48f6f819..8b81fb0f0 100644 --- a/src/qt/qt_settingsotherremovable.hpp +++ b/src/qt/qt_settingsotherremovable.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsOtherRemovable; } -class SettingsOtherRemovable : public QWidget -{ +class SettingsOtherRemovable : public QWidget { Q_OBJECT public: diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp index 34c000c87..dfa2c8853 100644 --- a/src/qt/qt_settingsports.cpp +++ b/src/qt/qt_settingsports.cpp @@ -32,19 +32,19 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsPorts::SettingsPorts(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsPorts) +SettingsPorts::SettingsPorts(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsPorts) { ui->setupUi(this); for (int i = 0; i < PARALLEL_MAX; i++) { - auto* cbox = findChild(QString("comboBoxLpt%1").arg(i+1)); - auto* model = cbox->model(); - int c = 0; - int selectedRow = 0; + auto *cbox = findChild(QString("comboBoxLpt%1").arg(i + 1)); + auto *model = cbox->model(); + int c = 0; + int selectedRow = 0; while (true) { - const char* lptName = lpt_device_get_name(c); + const char *lptName = lpt_device_get_name(c); if (lptName == nullptr) { break; } @@ -57,13 +57,13 @@ SettingsPorts::SettingsPorts(QWidget *parent) : } cbox->setCurrentIndex(selectedRow); - auto* checkBox = findChild(QString("checkBoxParallel%1").arg(i+1)); + auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); checkBox->setChecked(lpt_ports[i].enabled > 0); cbox->setEnabled(lpt_ports[i].enabled > 0); } for (int i = 0; i < SERIAL_MAX; i++) { - auto* checkBox = findChild(QString("checkBoxSerial%1").arg(i+1)); + auto *checkBox = findChild(QString("checkBoxSerial%1").arg(i + 1)); checkBox->setChecked(com_ports[i].enabled > 0); } } @@ -73,32 +73,42 @@ SettingsPorts::~SettingsPorts() delete ui; } -void SettingsPorts::save() { +void +SettingsPorts::save() +{ for (int i = 0; i < PARALLEL_MAX; i++) { - auto* cbox = findChild(QString("comboBoxLpt%1").arg(i+1)); - auto* checkBox = findChild(QString("checkBoxParallel%1").arg(i+1)); - lpt_ports[i].device = cbox->currentData().toInt(); + auto *cbox = findChild(QString("comboBoxLpt%1").arg(i + 1)); + auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); + lpt_ports[i].device = cbox->currentData().toInt(); lpt_ports[i].enabled = checkBox->isChecked() ? 1 : 0; } for (int i = 0; i < SERIAL_MAX; i++) { - auto* checkBox = findChild(QString("checkBoxSerial%1").arg(i+1)); + auto *checkBox = findChild(QString("checkBoxSerial%1").arg(i + 1)); com_ports[i].enabled = checkBox->isChecked() ? 1 : 0; } } -void SettingsPorts::on_checkBoxParallel1_stateChanged(int state) { +void +SettingsPorts::on_checkBoxParallel1_stateChanged(int state) +{ ui->comboBoxLpt1->setEnabled(state == Qt::Checked); } -void SettingsPorts::on_checkBoxParallel2_stateChanged(int state) { +void +SettingsPorts::on_checkBoxParallel2_stateChanged(int state) +{ ui->comboBoxLpt2->setEnabled(state == Qt::Checked); } -void SettingsPorts::on_checkBoxParallel3_stateChanged(int state) { +void +SettingsPorts::on_checkBoxParallel3_stateChanged(int state) +{ ui->comboBoxLpt3->setEnabled(state == Qt::Checked); } -void SettingsPorts::on_checkBoxParallel4_stateChanged(int state) { +void +SettingsPorts::on_checkBoxParallel4_stateChanged(int state) +{ ui->comboBoxLpt4->setEnabled(state == Qt::Checked); } diff --git a/src/qt/qt_settingsports.hpp b/src/qt/qt_settingsports.hpp index c5deef80a..5fa88e210 100644 --- a/src/qt/qt_settingsports.hpp +++ b/src/qt/qt_settingsports.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsPorts; } -class SettingsPorts : public QWidget -{ +class SettingsPorts : public QWidget { Q_OBJECT public: diff --git a/src/qt/qt_settingssound.cpp b/src/qt/qt_settingssound.cpp index 1c441b8ef..57686f7df 100644 --- a/src/qt/qt_settingssound.cpp +++ b/src/qt/qt_settingssound.cpp @@ -31,9 +31,9 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsSound::SettingsSound(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsSound) +SettingsSound::SettingsSound(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsSound) { ui->setupUi(this); onCurrentMachineChanged(machine); @@ -44,28 +44,35 @@ SettingsSound::~SettingsSound() delete ui; } -void SettingsSound::save() { - sound_card_current = ui->comboBoxSoundCard->currentData().toInt(); +void +SettingsSound::save() +{ + sound_card_current = ui->comboBoxSoundCard->currentData().toInt(); midi_output_device_current = ui->comboBoxMidiOut->currentData().toInt(); - midi_input_device_current = ui->comboBoxMidiIn->currentData().toInt(); - mpu401_standalone_enable = ui->checkBoxMPU401->isChecked() ? 1 : 0; - SSI2001 = ui->checkBoxSSI2001->isChecked() ? 1 : 0;; + midi_input_device_current = ui->comboBoxMidiIn->currentData().toInt(); + mpu401_standalone_enable = ui->checkBoxMPU401->isChecked() ? 1 : 0; + SSI2001 = ui->checkBoxSSI2001->isChecked() ? 1 : 0; + ; GAMEBLASTER = ui->checkBoxCMS->isChecked() ? 1 : 0; - GUS = ui->checkBoxGUS->isChecked() ? 1 : 0;; - sound_is_float = ui->checkBoxFloat32->isChecked() ? 1 : 0;; + GUS = ui->checkBoxGUS->isChecked() ? 1 : 0; + ; + sound_is_float = ui->checkBoxFloat32->isChecked() ? 1 : 0; + ; if (ui->radioButtonYMFM->isChecked()) fm_driver = FM_DRV_YMFM; else fm_driver = FM_DRV_NUKED; } -void SettingsSound::onCurrentMachineChanged(int machineId) { +void +SettingsSound::onCurrentMachineChanged(int machineId) +{ this->machineId = machineId; - auto* model = ui->comboBoxSoundCard->model(); - auto removeRows = model->rowCount(); - int c = 0; - int selectedRow = 0; + auto *model = ui->comboBoxSoundCard->model(); + auto removeRows = model->rowCount(); + int c = 0; + int selectedRow = 0; while (true) { /* Skip "internal" if machine doesn't have it. */ if ((c == 1) && (machine_has_flags(machineId, MACHINE_SOUND) == 0)) { @@ -73,8 +80,8 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { continue; } - auto* sound_dev = sound_card_getdevice(c); - QString name = DeviceConfig::DeviceName(sound_dev, sound_card_get_internal_name(c), 1); + auto *sound_dev = sound_card_getdevice(c); + QString name = DeviceConfig::DeviceName(sound_dev, sound_card_get_internal_name(c), 1); if (name.isEmpty()) { break; } @@ -95,9 +102,9 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { ui->comboBoxSoundCard->setCurrentIndex(-1); ui->comboBoxSoundCard->setCurrentIndex(selectedRow); - model = ui->comboBoxMidiOut->model(); - removeRows = model->rowCount(); - c = 0; + model = ui->comboBoxMidiOut->model(); + removeRows = model->rowCount(); + c = 0; selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(midi_out_device_getdevice(c), midi_out_device_get_internal_name(c), 0); @@ -118,9 +125,9 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { ui->comboBoxMidiOut->setCurrentIndex(-1); ui->comboBoxMidiOut->setCurrentIndex(selectedRow); - model = ui->comboBoxMidiIn->model(); - removeRows = model->rowCount(); - c = 0; + model = ui->comboBoxMidiIn->model(); + removeRows = model->rowCount(); + c = 0; selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(midi_in_device_getdevice(c), midi_in_device_get_internal_name(c), 0); @@ -148,7 +155,7 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { ui->checkBoxGUS->setChecked(GUS > 0); ui->checkBoxFloat32->setChecked(sound_is_float > 0); - bool hasIsa = machine_has_bus(machineId, MACHINE_BUS_ISA) > 0; + bool hasIsa = machine_has_bus(machineId, MACHINE_BUS_ISA) > 0; bool hasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0; ui->checkBoxCMS->setEnabled(hasIsa); ui->pushButtonConfigureCMS->setEnabled((GAMEBLASTER > 0) && hasIsa); @@ -157,17 +164,19 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { ui->checkBoxSSI2001->setEnabled(hasIsa); ui->pushButtonConfigureSSI2001->setEnabled((SSI2001 > 0) && hasIsa); switch (fm_driver) { - case FM_DRV_YMFM: - ui->radioButtonYMFM->setChecked(true); - break; - case FM_DRV_NUKED: - default: - ui->radioButtonNuked->setChecked(true); - break; + case FM_DRV_YMFM: + ui->radioButtonYMFM->setChecked(true); + break; + case FM_DRV_NUKED: + default: + ui->radioButtonNuked->setChecked(true); + break; } } -static bool allowMpu401(Ui::SettingsSound *ui) { +static bool +allowMpu401(Ui::SettingsSound *ui) +{ QString midiOut = midi_out_device_get_internal_name(ui->comboBoxMidiOut->currentData().toInt()); QString midiIn = midi_in_device_get_internal_name(ui->comboBoxMidiIn->currentData().toInt()); @@ -182,19 +191,24 @@ static bool allowMpu401(Ui::SettingsSound *ui) { return true; } -void SettingsSound::on_comboBoxSoundCard_currentIndexChanged(int index) { +void +SettingsSound::on_comboBoxSoundCard_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureSoundCard->setEnabled(sound_card_has_config(ui->comboBoxSoundCard->currentData().toInt())); } - -void SettingsSound::on_pushButtonConfigureSoundCard_clicked() { - DeviceConfig::ConfigureDevice(sound_card_getdevice(ui->comboBoxSoundCard->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureSoundCard_clicked() +{ + DeviceConfig::ConfigureDevice(sound_card_getdevice(ui->comboBoxSoundCard->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) { +void +SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) +{ if (index < 0) { return; } @@ -203,11 +217,15 @@ void SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) { ui->pushButtonConfigureMPU401->setEnabled(allowMpu401(ui) && ui->checkBoxMPU401->isChecked()); } -void SettingsSound::on_pushButtonConfigureMidiOut_clicked() { - DeviceConfig::ConfigureDevice(midi_out_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureMidiOut_clicked() +{ + DeviceConfig::ConfigureDevice(midi_out_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) { +void +SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) +{ if (index < 0) { return; } @@ -216,42 +234,60 @@ void SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) { ui->pushButtonConfigureMPU401->setEnabled(allowMpu401(ui) && ui->checkBoxMPU401->isChecked()); } -void SettingsSound::on_pushButtonConfigureMidiIn_clicked() { - DeviceConfig::ConfigureDevice(midi_in_device_getdevice(ui->comboBoxMidiIn->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureMidiIn_clicked() +{ + DeviceConfig::ConfigureDevice(midi_in_device_getdevice(ui->comboBoxMidiIn->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_checkBoxMPU401_stateChanged(int state) { +void +SettingsSound::on_checkBoxMPU401_stateChanged(int state) +{ ui->pushButtonConfigureMPU401->setEnabled(state == Qt::Checked); } -void SettingsSound::on_checkBoxSSI2001_stateChanged(int state) { +void +SettingsSound::on_checkBoxSSI2001_stateChanged(int state) +{ ui->pushButtonConfigureSSI2001->setEnabled(state == Qt::Checked); } -void SettingsSound::on_checkBoxCMS_stateChanged(int state) { +void +SettingsSound::on_checkBoxCMS_stateChanged(int state) +{ ui->pushButtonConfigureCMS->setEnabled(state == Qt::Checked); } -void SettingsSound::on_checkBoxGUS_stateChanged(int state) { +void +SettingsSound::on_checkBoxGUS_stateChanged(int state) +{ ui->pushButtonConfigureGUS->setEnabled(state == Qt::Checked); } -void SettingsSound::on_pushButtonConfigureMPU401_clicked() { +void +SettingsSound::on_pushButtonConfigureMPU401_clicked() +{ if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { - DeviceConfig::ConfigureDevice(&mpu401_mca_device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(&mpu401_mca_device, 0, qobject_cast(Settings::settings)); } else { - DeviceConfig::ConfigureDevice(&mpu401_device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(&mpu401_device, 0, qobject_cast(Settings::settings)); } } -void SettingsSound::on_pushButtonConfigureSSI2001_clicked() { - DeviceConfig::ConfigureDevice(&ssi2001_device, 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureSSI2001_clicked() +{ + DeviceConfig::ConfigureDevice(&ssi2001_device, 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_pushButtonConfigureCMS_clicked() { - DeviceConfig::ConfigureDevice(&cms_device, 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureCMS_clicked() +{ + DeviceConfig::ConfigureDevice(&cms_device, 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_pushButtonConfigureGUS_clicked() { - DeviceConfig::ConfigureDevice(&gus_device, 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureGUS_clicked() +{ + DeviceConfig::ConfigureDevice(&gus_device, 0, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingssound.hpp b/src/qt/qt_settingssound.hpp index c649eb2a2..e0bc2e4f8 100644 --- a/src/qt/qt_settingssound.hpp +++ b/src/qt/qt_settingssound.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsSound; } -class SettingsSound : public QWidget -{ +class SettingsSound : public QWidget { Q_OBJECT public: @@ -38,7 +37,7 @@ private slots: private: Ui::SettingsSound *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSSOUND_HPP diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 7664fdd5f..2aecab568 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -33,9 +33,9 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsStorageControllers::SettingsStorageControllers(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsStorageControllers) +SettingsStorageControllers::SettingsStorageControllers(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsStorageControllers) { ui->setupUi(this); @@ -49,27 +49,31 @@ SettingsStorageControllers::~SettingsStorageControllers() delete ui; } -void SettingsStorageControllers::save() { +void +SettingsStorageControllers::save() +{ /* Storage devices category */ for (int i = 0; i < SCSI_BUS_MAX; ++i) { - auto* cbox = findChild(QString("comboBoxSCSI%1").arg(i+1)); + auto *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); scsi_card_current[i] = cbox->currentData().toInt(); } - hdc_current = ui->comboBoxHD->currentData().toInt(); - fdc_type = ui->comboBoxFD->currentData().toInt(); + hdc_current = ui->comboBoxHD->currentData().toInt(); + fdc_type = ui->comboBoxFD->currentData().toInt(); ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0; ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0; cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0; } -void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { +void +SettingsStorageControllers::onCurrentMachineChanged(int machineId) +{ this->machineId = machineId; /*HD controller config*/ - auto* model = ui->comboBoxHD->model(); - auto removeRows = model->rowCount(); - int c = 0; - int selectedRow = 0; + auto *model = ui->comboBoxHD->model(); + auto removeRows = model->rowCount(); + int c = 0; + int selectedRow = 0; while (true) { /* Skip "internal" if machine doesn't have it. */ if ((c == 1) && (machine_has_flags(machineId, MACHINE_HDC) == 0)) { @@ -83,7 +87,7 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { } if (hdc_available(c)) { - auto* hdc_dev = hdc_get_device(c); + auto *hdc_dev = hdc_get_device(c); if (device_is_valid(hdc_dev, machineId)) { int row = Models::AddEntry(model, name, c); @@ -100,9 +104,9 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { ui->comboBoxHD->setCurrentIndex(selectedRow); /*FD controller config*/ - model = ui->comboBoxFD->model(); - removeRows = model->rowCount(); - c = 0; + model = ui->comboBoxFD->model(); + removeRows = model->rowCount(); + c = 0; selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(fdc_card_getdevice(c), fdc_card_get_internal_name(c), 1); @@ -111,7 +115,7 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { } if (fdc_card_available(c)) { - auto* fdc_dev = fdc_card_getdevice(c); + auto *fdc_dev = fdc_card_getdevice(c); if (device_is_valid(fdc_dev, machineId)) { int row = Models::AddEntry(model, name, c); @@ -128,10 +132,10 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { ui->comboBoxFD->setCurrentIndex(selectedRow); for (int i = 0; i < SCSI_BUS_MAX; ++i) { - auto* cbox = findChild(QString("comboBoxSCSI%1").arg(i+1)); - model = cbox->model(); - removeRows = model->rowCount(); - c = 0; + auto *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); + model = cbox->model(); + removeRows = model->rowCount(); + c = 0; selectedRow = 0; while (true) { @@ -141,7 +145,7 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { } if (scsi_card_available(c)) { - auto* scsi_dev = scsi_card_getdevice(c); + auto *scsi_dev = scsi_card_getdevice(c); if (device_is_valid(scsi_dev, machineId)) { int row = Models::AddEntry(model, name, c); if (c == scsi_card_current[i]) { @@ -165,86 +169,116 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { ui->checkBoxQuaternaryIDE->setChecked(ui->checkBoxQuaternaryIDE->isEnabled() && ide_qua_enabled); } -void SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonHD->setEnabled(hdc_has_config(ui->comboBoxHD->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_comboBoxFD_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxFD_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonFD->setEnabled(hdc_has_config(ui->comboBoxFD->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_checkBoxTertiaryIDE_stateChanged(int arg1) { +void +SettingsStorageControllers::on_checkBoxTertiaryIDE_stateChanged(int arg1) +{ ui->pushButtonTertiaryIDE->setEnabled(arg1 == Qt::Checked); } - -void SettingsStorageControllers::on_checkBoxQuaternaryIDE_stateChanged(int arg1) { +void +SettingsStorageControllers::on_checkBoxQuaternaryIDE_stateChanged(int arg1) +{ ui->pushButtonQuaternaryIDE->setEnabled(arg1 == Qt::Checked); } -void SettingsStorageControllers::on_pushButtonHD_clicked() { - DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonHD_clicked() +{ + DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonFD_clicked() { - DeviceConfig::ConfigureDevice(fdc_card_getdevice(ui->comboBoxFD->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonFD_clicked() +{ + DeviceConfig::ConfigureDevice(fdc_card_getdevice(ui->comboBoxFD->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonTertiaryIDE_clicked() { - DeviceConfig::ConfigureDevice(&ide_ter_device, 0, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonTertiaryIDE_clicked() +{ + DeviceConfig::ConfigureDevice(&ide_ter_device, 0, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonQuaternaryIDE_clicked() { - DeviceConfig::ConfigureDevice(&ide_qua_device, 0, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonQuaternaryIDE_clicked() +{ + DeviceConfig::ConfigureDevice(&ide_qua_device, 0, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_comboBoxSCSI1_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxSCSI1_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonSCSI1->setEnabled(scsi_card_has_config(ui->comboBoxSCSI1->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_comboBoxSCSI2_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxSCSI2_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonSCSI2->setEnabled(scsi_card_has_config(ui->comboBoxSCSI2->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_comboBoxSCSI3_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxSCSI3_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonSCSI3->setEnabled(scsi_card_has_config(ui->comboBoxSCSI3->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_comboBoxSCSI4_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxSCSI4_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonSCSI4->setEnabled(scsi_card_has_config(ui->comboBoxSCSI4->currentData().toInt()) > 0); } - -void SettingsStorageControllers::on_pushButtonSCSI1_clicked() { - DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI1->currentData().toInt()), 1, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonSCSI1_clicked() +{ + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI1->currentData().toInt()), 1, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonSCSI2_clicked() { - DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI2->currentData().toInt()), 2, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonSCSI2_clicked() +{ + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI2->currentData().toInt()), 2, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonSCSI3_clicked() { - DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI3->currentData().toInt()), 3, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonSCSI3_clicked() +{ + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI3->currentData().toInt()), 3, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonSCSI4_clicked() { - DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonSCSI4_clicked() +{ + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingsstoragecontrollers.hpp b/src/qt/qt_settingsstoragecontrollers.hpp index e4596b567..7e9cd9d6c 100644 --- a/src/qt/qt_settingsstoragecontrollers.hpp +++ b/src/qt/qt_settingsstoragecontrollers.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsStorageControllers; } -class SettingsStorageControllers : public QWidget -{ +class SettingsStorageControllers : public QWidget { Q_OBJECT public: @@ -40,7 +39,7 @@ private slots: private: Ui::SettingsStorageControllers *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSSTORAGECONTROLLERS_HPP diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 44a69c144..cd27e1c0e 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -47,16 +47,21 @@ SoftwareRenderer::SoftwareRenderer(QWidget *parent) #endif } -void SoftwareRenderer::paintEvent(QPaintEvent* event) { - (void)event; +void +SoftwareRenderer::paintEvent(QPaintEvent *event) +{ + (void) event; onPaint(this); } -void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { +void +SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) +{ /* TODO: should look into deleteLater() */ - auto tval = this; - void* nuldata = 0; - if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; + auto tval = this; + void *nuldata = 0; + if (memcmp(&tval, &nuldata, sizeof(void *)) == 0) + return; auto origSource = source; cur_image = buf_idx; @@ -64,11 +69,14 @@ void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { source.setRect(x, y, w, h); - if (source != origSource) onResize(this->width(), this->height()); + if (source != origSource) + onResize(this->width(), this->height()); update(); } -void SoftwareRenderer::resizeEvent(QResizeEvent *event) { +void +SoftwareRenderer::resizeEvent(QResizeEvent *event) +{ onResize(width(), height()); #ifdef __HAIKU__ QWidget::resizeEvent(event); @@ -77,7 +85,8 @@ void SoftwareRenderer::resizeEvent(QResizeEvent *event) { #endif } -bool SoftwareRenderer::event(QEvent *event) +bool +SoftwareRenderer::event(QEvent *event) { bool res = false; if (!eventDelegate(event, res)) @@ -89,7 +98,9 @@ bool SoftwareRenderer::event(QEvent *event) return res; } -void SoftwareRenderer::onPaint(QPaintDevice* device) { +void +SoftwareRenderer::onPaint(QPaintDevice *device) +{ if (cur_image == -1) return; @@ -104,9 +115,10 @@ void SoftwareRenderer::onPaint(QPaintDevice* device) { painter.drawImage(destination, *images[cur_image], source); } -std::vector> SoftwareRenderer::getBuffers() +std::vector> +SoftwareRenderer::getBuffers() { - std::vector> buffers; + std::vector> buffers; buffers.push_back(std::make_tuple(images[0]->bits(), &buf_usage[0])); buffers.push_back(std::make_tuple(images[1]->bits(), &buf_usage[1])); diff --git a/src/qt/qt_softwarerenderer.hpp b/src/qt/qt_softwarerenderer.hpp index 5b0f7b0f5..ec64f7000 100644 --- a/src/qt/qt_softwarerenderer.hpp +++ b/src/qt/qt_softwarerenderer.hpp @@ -9,29 +9,28 @@ #include "qt_renderercommon.hpp" class SoftwareRenderer : - #ifdef __HAIKU__ - public QWidget, - #else - public QRasterWindow, - #endif - public RendererCommon -{ +#ifdef __HAIKU__ + public QWidget, +#else + public QRasterWindow, +#endif + public RendererCommon { Q_OBJECT public: explicit SoftwareRenderer(QWidget *parent = nullptr); - void paintEvent(QPaintEvent* event) override; + void paintEvent(QPaintEvent *event) override; - std::vector> getBuffers() override; + std::vector> getBuffers() override; public slots: void onBlit(int buf_idx, int x, int y, int w, int h); protected: std::array, 2> images; - int cur_image = -1; + int cur_image = -1; - void onPaint(QPaintDevice* device); + void onPaint(QPaintDevice *device); void resizeEvent(QResizeEvent *event) override; bool event(QEvent *event) override; }; diff --git a/src/qt/qt_soundgain.cpp b/src/qt/qt_soundgain.cpp index 26ac3dd73..9283ae42e 100644 --- a/src/qt/qt_soundgain.cpp +++ b/src/qt/qt_soundgain.cpp @@ -17,16 +17,15 @@ #include "qt_soundgain.hpp" #include "ui_qt_soundgain.h" -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/sound.h> } -SoundGain::SoundGain(QWidget *parent) : - QDialog(parent), - ui(new Ui::SoundGain) +SoundGain::SoundGain(QWidget *parent) + : QDialog(parent) + , ui(new Ui::SoundGain) { ui->setupUi(this); ui->verticalSlider->setValue(sound_gain); @@ -38,13 +37,14 @@ SoundGain::~SoundGain() delete ui; } -void SoundGain::on_verticalSlider_valueChanged(int value) +void +SoundGain::on_verticalSlider_valueChanged(int value) { sound_gain = value; } - -void SoundGain::on_SoundGain_rejected() +void +SoundGain::on_SoundGain_rejected() { sound_gain = sound_gain_orig; } diff --git a/src/qt/qt_soundgain.hpp b/src/qt/qt_soundgain.hpp index 0e19bab53..e4b52d959 100644 --- a/src/qt/qt_soundgain.hpp +++ b/src/qt/qt_soundgain.hpp @@ -7,8 +7,7 @@ namespace Ui { class SoundGain; } -class SoundGain : public QDialog -{ +class SoundGain : public QDialog { Q_OBJECT public: @@ -22,7 +21,7 @@ private slots: private: Ui::SoundGain *ui; - int sound_gain_orig; + int sound_gain_orig; }; #endif // QT_SOUNDGAIN_HPP diff --git a/src/qt/qt_specifydimensions.cpp b/src/qt/qt_specifydimensions.cpp index 1fc294d79..e2aa24a9b 100644 --- a/src/qt/qt_specifydimensions.cpp +++ b/src/qt/qt_specifydimensions.cpp @@ -27,19 +27,18 @@ #include #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/ui.h> #include <86box/video.h> } -extern MainWindow* main_window; +extern MainWindow *main_window; -SpecifyDimensions::SpecifyDimensions(QWidget *parent) : - QDialog(parent), - ui(new Ui::SpecifyDimensions) +SpecifyDimensions::SpecifyDimensions(QWidget *parent) + : QDialog(parent) + , ui(new Ui::SpecifyDimensions) { ui->setupUi(this); ui->checkBox->setChecked(vid_resize == 2); @@ -59,16 +58,16 @@ SpecifyDimensions::~SpecifyDimensions() delete ui; } -void SpecifyDimensions::on_SpecifyDimensions_accepted() +void +SpecifyDimensions::on_SpecifyDimensions_accepted() { - if (ui->checkBox->isChecked()) - { + if (ui->checkBox->isChecked()) { vid_resize = 2; main_window->setWindowFlag(Qt::WindowMaximizeButtonHint, false); main_window->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint); window_remember = 0; - fixed_size_x = ui->spinBoxWidth->value(); - fixed_size_y = ui->spinBoxHeight->value(); + fixed_size_x = ui->spinBoxWidth->value(); + fixed_size_y = ui->spinBoxHeight->value(); main_window->resizeContents(fixed_size_x, fixed_size_y); @@ -81,21 +80,19 @@ void SpecifyDimensions::on_SpecifyDimensions_accepted() emit main_window->resizeContentsMonitor(fixed_size_x, fixed_size_y, i); if (show_second_monitors) { main_window->renderers[i]->show(); - main_window->renderers[i]->switchRenderer((RendererStack::Renderer)vid_api); + main_window->renderers[i]->switchRenderer((RendererStack::Renderer) vid_api); } } } - main_window->ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api); - } - else - { + main_window->ui->stackedWidget->switchRenderer((RendererStack::Renderer) vid_api); + } else { main_window->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); main_window->ui->actionResizable_window->setChecked(false); vid_resize = 0; main_window->ui->actionResizable_window->trigger(); window_remember = 1; - window_w = ui->spinBoxWidth->value(); - window_h = ui->spinBoxHeight->value(); + window_w = ui->spinBoxWidth->value(); + window_h = ui->spinBoxHeight->value(); main_window->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); emit main_window->resizeContents(ui->spinBoxWidth->value(), ui->spinBoxHeight->value()); for (int i = 1; i < MONITORS_NUM; i++) { @@ -104,8 +101,10 @@ void SpecifyDimensions::on_SpecifyDimensions_accepted() main_window->renderers[i]->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, false); emit main_window->resizeContentsMonitor(ui->spinBoxWidth->value(), ui->spinBoxHeight->value(), i); main_window->renderers[i]->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); - if (show_second_monitors) { main_window->renderers[i]->show(); - main_window->renderers[i]->switchRenderer((RendererStack::Renderer)vid_api); } + if (show_second_monitors) { + main_window->renderers[i]->show(); + main_window->renderers[i]->switchRenderer((RendererStack::Renderer) vid_api); + } } } vid_resize = 1; diff --git a/src/qt/qt_specifydimensions.h b/src/qt/qt_specifydimensions.h index 2aa820455..812e38707 100644 --- a/src/qt/qt_specifydimensions.h +++ b/src/qt/qt_specifydimensions.h @@ -7,8 +7,7 @@ namespace Ui { class SpecifyDimensions; } -class SpecifyDimensions : public QDialog -{ +class SpecifyDimensions : public QDialog { Q_OBJECT public: diff --git a/src/qt/qt_styleoverride.cpp b/src/qt/qt_styleoverride.cpp index a2af1296b..6efe523d9 100644 --- a/src/qt/qt_styleoverride.cpp +++ b/src/qt/qt_styleoverride.cpp @@ -19,11 +19,12 @@ #include #include -int StyleOverride::styleHint( - StyleHint hint, - const QStyleOption *option, - const QWidget *widget, - QStyleHintReturn *returnData) const +int +StyleOverride::styleHint( + StyleHint hint, + const QStyleOption *option, + const QWidget *widget, + QStyleHintReturn *returnData) const { /* Disable using menu with alt key */ if (hint == QStyle::SH_MenuBar_AltKeyNavigation) @@ -32,7 +33,8 @@ int StyleOverride::styleHint( return QProxyStyle::styleHint(hint, option, widget, returnData); } -void StyleOverride::polish(QWidget* widget) +void +StyleOverride::polish(QWidget *widget) { QProxyStyle::polish(widget); /* Disable title bar context help buttons globally as they are unused. */ @@ -48,7 +50,7 @@ void StyleOverride::polish(QWidget* widget) widget->setWindowFlag(Qt::WindowContextHelpButtonHint, false); } - if (qobject_cast(widget)) { - qobject_cast(widget)->view()->setMinimumWidth(widget->minimumSizeHint().width()); + if (qobject_cast(widget)) { + qobject_cast(widget)->view()->setMinimumWidth(widget->minimumSizeHint().width()); } } diff --git a/src/qt/qt_styleoverride.hpp b/src/qt/qt_styleoverride.hpp index 9a2223322..c04d01a12 100644 --- a/src/qt/qt_styleoverride.hpp +++ b/src/qt/qt_styleoverride.hpp @@ -5,16 +5,15 @@ #include #include -class StyleOverride : public QProxyStyle -{ +class StyleOverride : public QProxyStyle { public: int styleHint( - StyleHint hint, - const QStyleOption *option = nullptr, - const QWidget *widget = nullptr, - QStyleHintReturn *returnData = nullptr) const override; + StyleHint hint, + const QStyleOption *option = nullptr, + const QWidget *widget = nullptr, + QStyleHintReturn *returnData = nullptr) const override; - void polish(QWidget* widget) override; + void polish(QWidget *widget) override; }; #endif diff --git a/src/qt/qt_translations.qrc b/src/qt/qt_translations.qrc index 1de212273..845099436 100644 --- a/src/qt/qt_translations.qrc +++ b/src/qt/qt_translations.qrc @@ -1,24 +1,25 @@ - 86box_cs-CZ.qm - 86box_de-DE.qm - 86box_en-US.qm - 86box_en-GB.qm - 86box_es-ES.qm - 86box_fi-FI.qm - 86box_fr-FR.qm - 86box_hr-HR.qm - 86box_hu-HU.qm - 86box_it-IT.qm - 86box_ja-JP.qm - 86box_ko-KR.qm - 86box_pl-PL.qm - 86box_pt-BR.qm - 86box_pt-PT.qm - 86box_ru-RU.qm - 86box_sl-SI.qm - 86box_tr-TR.qm - 86box_uk-UA.qm - 86box_zh-CN.qm + 86box_cs-CZ.qm + 86box_de-DE.qm + 86box_en-US.qm + 86box_en-GB.qm + 86box_es-ES.qm + 86box_fi-FI.qm + 86box_fr-FR.qm + 86box_hr-HR.qm + 86box_hu-HU.qm + 86box_it-IT.qm + 86box_ja-JP.qm + 86box_ko-KR.qm + 86box_pl-PL.qm + 86box_pt-BR.qm + 86box_pt-PT.qm + 86box_ru-RU.qm + 86box_sl-SI.qm + 86box_tr-TR.qm + 86box_uk-UA.qm + 86box_zh-CN.qm + 86box_zh-TW.qm diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 09199bdac..a2864f3ea 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -27,7 +27,7 @@ #include "qt_mainwindow.hpp" #include "qt_machinestatus.hpp" -MainWindow* main_window = nullptr; +MainWindow *main_window = nullptr; static QString sb_text, sb_buguitext, sb_mt32lcdtext; @@ -60,7 +60,8 @@ plat_delay_ms(uint32_t count) QThread::msleep(count); } -wchar_t* ui_window_title(wchar_t* str) +wchar_t * +ui_window_title(wchar_t *str) { if (str == nullptr) { static wchar_t title[512]; @@ -73,49 +74,65 @@ wchar_t* ui_window_title(wchar_t* str) return str; } -extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index) +extern "C" void +qt_blit(int x, int y, int w, int h, int monitor_index) { main_window->blitToWidget(x, y, w, h, monitor_index); } -void mouse_poll() { +void +mouse_poll() +{ main_window->pollMouse(); } extern "C" int vid_resize; -void plat_resize_request(int w, int h, int monitor_index) +void +plat_resize_request(int w, int h, int monitor_index) { - if (video_fullscreen || is_quit) return; + if (video_fullscreen || is_quit) + return; if (vid_resize & 2) { plat_resize_monitor(fixed_size_x, fixed_size_y, monitor_index); - } - else { + } else { plat_resize_monitor(w, h, monitor_index); } } -void plat_resize_monitor(int w, int h, int monitor_index) { - if (monitor_index >= 1) main_window->resizeContentsMonitor(w, h, monitor_index); - else main_window->resizeContents(w, h); +void +plat_resize_monitor(int w, int h, int monitor_index) +{ + if (monitor_index >= 1) + main_window->resizeContentsMonitor(w, h, monitor_index); + else + main_window->resizeContents(w, h); } -void plat_setfullscreen(int on) { +void +plat_setfullscreen(int on) +{ main_window->setFullscreen(on > 0 ? true : false); } -void plat_mouse_capture(int on) { +void +plat_mouse_capture(int on) +{ if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE) && !machine_has_mouse()) return; main_window->setMouseCapture(on > 0 ? true : false); } -int ui_msgbox_header(int flags, void *header, void* message) { - if (header <= (void*)7168) header = plat_get_string((uintptr_t)header); - if (message <= (void*)7168) message = plat_get_string((uintptr_t)message); +int +ui_msgbox_header(int flags, void *header, void *message) +{ + if (header <= (void *) 7168) + header = plat_get_string((uintptr_t) header); + if (message <= (void *) 7168) + message = plat_get_string((uintptr_t) message); - auto hdr = (flags & MBX_ANSI) ? QString((char*)header) : QString::fromWCharArray(reinterpret_cast(header)); - auto msg = (flags & MBX_ANSI) ? QString((char*)message) : QString::fromWCharArray(reinterpret_cast(message)); + auto hdr = (flags & MBX_ANSI) ? QString((char *) header) : QString::fromWCharArray(reinterpret_cast(header)); + auto msg = (flags & MBX_ANSI) ? QString((char *) message) : QString::fromWCharArray(reinterpret_cast(message)); // any error in early init if (main_window == nullptr) { @@ -129,60 +146,81 @@ int ui_msgbox_header(int flags, void *header, void* message) { return 0; } -void ui_init_monitor(int monitor_index) { +void +ui_init_monitor(int monitor_index) +{ if (QThread::currentThread() == main_window->thread()) { emit main_window->initRendererMonitor(monitor_index); - } - else emit main_window->initRendererMonitorForNonQtThread(monitor_index); + } else + emit main_window->initRendererMonitorForNonQtThread(monitor_index); } -void ui_deinit_monitor(int monitor_index) { +void +ui_deinit_monitor(int monitor_index) +{ if (QThread::currentThread() == main_window->thread()) { emit main_window->destroyRendererMonitor(monitor_index); - } - else emit main_window->destroyRendererMonitorForNonQtThread(monitor_index); + } else + emit main_window->destroyRendererMonitorForNonQtThread(monitor_index); } -int ui_msgbox(int flags, void *message) { +int +ui_msgbox(int flags, void *message) +{ return ui_msgbox_header(flags, nullptr, message); } -void ui_sb_update_text() { - emit main_window->statusBarMessage( !sb_mt32lcdtext.isEmpty() ? sb_mt32lcdtext : sb_text.isEmpty() ? sb_buguitext : sb_text); +void +ui_sb_update_text() +{ + emit main_window->statusBarMessage(!sb_mt32lcdtext.isEmpty() ? sb_mt32lcdtext : sb_text.isEmpty() ? sb_buguitext + : sb_text); } -void ui_sb_mt32lcd(char* str) +void +ui_sb_mt32lcd(char *str) { sb_mt32lcdtext = QString(str); ui_sb_update_text(); } -void ui_sb_set_text_w(wchar_t *wstr) { +void +ui_sb_set_text_w(wchar_t *wstr) +{ sb_text = QString::fromWCharArray(wstr); ui_sb_update_text(); } -void ui_sb_set_text(char *str) { +void +ui_sb_set_text(char *str) +{ sb_text = str; ui_sb_update_text(); } void -ui_sb_update_tip(int arg) { +ui_sb_update_tip(int arg) +{ main_window->updateStatusBarTip(arg); } void -ui_sb_update_panes() { +ui_sb_update_panes() +{ main_window->updateStatusBarPanes(); } -void ui_sb_bugui(char *str) { +void +ui_sb_bugui(char *str) +{ sb_buguitext = str; - ui_sb_update_text();; + ui_sb_update_text(); + ; } -void ui_sb_set_ready(int ready) { +void +ui_sb_set_ready(int ready) +{ if (ready == 0) { ui_sb_bugui(nullptr); ui_sb_set_text(nullptr); @@ -190,72 +228,73 @@ void ui_sb_set_ready(int ready) { } void -ui_sb_update_icon_state(int tag, int state) { +ui_sb_update_icon_state(int tag, int state) +{ int category = tag & 0xfffffff0; - int item = tag & 0xf; + int item = tag & 0xf; switch (category) { - case SB_CASSETTE: - machine_status.cassette.empty = state > 0 ? true : false; - break; - case SB_CARTRIDGE: - machine_status.cartridge[item].empty = state > 0 ? true : false; - break; - case SB_FLOPPY: - machine_status.fdd[item].empty = state > 0 ? true : false; - break; - case SB_CDROM: - machine_status.cdrom[item].empty = state > 0 ? true : false; - break; - case SB_ZIP: - machine_status.zip[item].empty = state > 0 ? true : false; - break; - case SB_MO: - machine_status.mo[item].empty = state > 0 ? true : false; - break; - case SB_HDD: - break; - case SB_NETWORK: - machine_status.net[item].empty = state > 0 ? true : false; - break; - case SB_SOUND: - break; - case SB_TEXT: - break; + case SB_CASSETTE: + machine_status.cassette.empty = state > 0 ? true : false; + break; + case SB_CARTRIDGE: + machine_status.cartridge[item].empty = state > 0 ? true : false; + break; + case SB_FLOPPY: + machine_status.fdd[item].empty = state > 0 ? true : false; + break; + case SB_CDROM: + machine_status.cdrom[item].empty = state > 0 ? true : false; + break; + case SB_ZIP: + machine_status.zip[item].empty = state > 0 ? true : false; + break; + case SB_MO: + machine_status.mo[item].empty = state > 0 ? true : false; + break; + case SB_HDD: + break; + case SB_NETWORK: + machine_status.net[item].empty = state > 0 ? true : false; + break; + case SB_SOUND: + break; + case SB_TEXT: + break; } } void -ui_sb_update_icon(int tag, int active) { +ui_sb_update_icon(int tag, int active) +{ int category = tag & 0xfffffff0; - int item = tag & 0xf; + int item = tag & 0xf; switch (category) { - case SB_CASSETTE: - break; - case SB_CARTRIDGE: - break; - case SB_FLOPPY: - machine_status.fdd[item].active = active > 0 ? true : false; - break; - case SB_CDROM: - machine_status.cdrom[item].active = active > 0 ? true : false; - break; - case SB_ZIP: - machine_status.zip[item].active = active > 0 ? true : false; - break; - case SB_MO: - machine_status.mo[item].active = active > 0 ? true : false; - break; - case SB_HDD: - machine_status.hdd[item].active = active > 0 ? true : false; - break; - case SB_NETWORK: - machine_status.net[item].active = active > 0 ? true : false; - break; - case SB_SOUND: - break; - case SB_TEXT: - break; + case SB_CASSETTE: + break; + case SB_CARTRIDGE: + break; + case SB_FLOPPY: + machine_status.fdd[item].active = active > 0 ? true : false; + break; + case SB_CDROM: + machine_status.cdrom[item].active = active > 0 ? true : false; + break; + case SB_ZIP: + machine_status.zip[item].active = active > 0 ? true : false; + break; + case SB_MO: + machine_status.mo[item].active = active > 0 ? true : false; + break; + case SB_HDD: + machine_status.hdd[item].active = active > 0 ? true : false; + break; + case SB_NETWORK: + machine_status.net[item].active = active > 0 ? true : false; + break; + case SB_SOUND: + break; + case SB_TEXT: + break; } } - } diff --git a/src/qt/qt_unixmanagerfilter.cpp b/src/qt/qt_unixmanagerfilter.cpp index 9df6da5cb..d1091198d 100644 --- a/src/qt/qt_unixmanagerfilter.cpp +++ b/src/qt/qt_unixmanagerfilter.cpp @@ -18,59 +18,44 @@ #include "qt_unixmanagerfilter.hpp" -UnixManagerSocket::UnixManagerSocket(QObject* obj) +UnixManagerSocket::UnixManagerSocket(QObject *obj) : QLocalSocket(obj) { connect(this, &QLocalSocket::readyRead, this, &UnixManagerSocket::readyToRead); } -void UnixManagerSocket::readyToRead() +void +UnixManagerSocket::readyToRead() { - if (canReadLine()) - { + if (canReadLine()) { QByteArray line = readLine(); - if (line.size()) - { + if (line.size()) { line.resize(line.size() - 1); - if (line == "showsettings") - { + if (line == "showsettings") { emit showsettings(); - } - else if (line == "pause") - { + } else if (line == "pause") { emit pause(); - } - else if (line == "cad") - { + } else if (line == "cad") { emit ctrlaltdel(); - } - else if (line == "reset") - { + } else if (line == "reset") { emit resetVM(); - } - else if (line == "shutdownnoprompt") - { + } else if (line == "shutdownnoprompt") { emit force_shutdown(); - } - else if (line == "shutdown") - { + } else if (line == "shutdown") { emit request_shutdown(); } } } } -bool UnixManagerSocket::eventFilter(QObject *obj, QEvent *event) +bool +UnixManagerSocket::eventFilter(QObject *obj, QEvent *event) { - if (state() == QLocalSocket::ConnectedState) - { - if (event->type() == QEvent::WindowBlocked) - { - write(QByteArray{"1"}); - } - else if (event->type() == QEvent::WindowUnblocked) - { - write(QByteArray{"0"}); + if (state() == QLocalSocket::ConnectedState) { + if (event->type() == QEvent::WindowBlocked) { + write(QByteArray { "1" }); + } else if (event->type() == QEvent::WindowUnblocked) { + write(QByteArray { "0" }); } } diff --git a/src/qt/qt_unixmanagerfilter.hpp b/src/qt/qt_unixmanagerfilter.hpp index 33b0f76a8..eca373b47 100644 --- a/src/qt/qt_unixmanagerfilter.hpp +++ b/src/qt/qt_unixmanagerfilter.hpp @@ -10,7 +10,7 @@ * * Authors: * Teemu Korhonen - Cacodemon345 + Cacodemon345 * * Copyright 2022 Teemu Korhonen * Copyright 2022 Cacodemon345 @@ -27,11 +27,10 @@ * Filters messages from VM-manager and * window blocked events to notify about open modal dialogs. */ -class UnixManagerSocket : public QLocalSocket -{ +class UnixManagerSocket : public QLocalSocket { Q_OBJECT public: - UnixManagerSocket(QObject* object = nullptr); + UnixManagerSocket(QObject *object = nullptr); signals: void pause(); void ctrlaltdel(); diff --git a/src/qt/qt_util.cpp b/src/qt/qt_util.cpp index 771c6d94a..876a4b047 100644 --- a/src/qt/qt_util.cpp +++ b/src/qt/qt_util.cpp @@ -19,42 +19,41 @@ #include #include #if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0) -#include +# include #endif #include "qt_util.hpp" -namespace util +namespace util { +QScreen * +screenOfWidget(QWidget *widget) { - QScreen* screenOfWidget(QWidget* widget) - { #if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0) - return QApplication::screens()[QApplication::desktop()->screenNumber(widget) == -1 ? 0 : QApplication::desktop()->screenNumber(widget)]; + return QApplication::screens()[QApplication::desktop()->screenNumber(widget) == -1 ? 0 : QApplication::desktop()->screenNumber(widget)]; #else - return widget->screen(); + return widget->screen(); #endif - } +} - QString DlgFilter(std::initializer_list extensions, bool last) - { - QStringList temp; +QString +DlgFilter(std::initializer_list extensions, bool last) +{ + QStringList temp; - for (auto ext : extensions) - { + for (auto ext : extensions) { #ifdef Q_OS_UNIX - if (ext == "*") - { - temp.append("*"); - continue; - } - temp.append("*." % ext.toUpper()); -#endif - temp.append("*." % ext); + if (ext == "*") { + temp.append("*"); + continue; } + temp.append("*." % ext.toUpper()); +#endif + temp.append("*." % ext); + } #ifdef Q_OS_UNIX - temp.removeDuplicates(); + temp.removeDuplicates(); #endif - return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); - } + return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); +} } diff --git a/src/qt/qt_util.hpp b/src/qt/qt_util.hpp index 4e62c8e12..6ecd904b3 100644 --- a/src/qt/qt_util.hpp +++ b/src/qt/qt_util.hpp @@ -7,12 +7,11 @@ #include class QScreen; -namespace util -{ - /* Creates extension list for qt filedialog */ - QString DlgFilter(std::initializer_list extensions, bool last = false); - /* Returns screen the widget is on */ - QScreen* screenOfWidget(QWidget* widget); +namespace util { +/* Creates extension list for qt filedialog */ +QString DlgFilter(std::initializer_list extensions, bool last = false); +/* Returns screen the widget is on */ +QScreen *screenOfWidget(QWidget *widget); }; #endif diff --git a/src/qt/qt_vulkanrenderer.cpp b/src/qt/qt_vulkanrenderer.cpp index c62154669..41791a026 100644 --- a/src/qt/qt_vulkanrenderer.cpp +++ b/src/qt/qt_vulkanrenderer.cpp @@ -35,11 +35,10 @@ #include #include "qt_vulkanrenderer.hpp" #if QT_CONFIG(vulkan) -#include +# include -extern "C" -{ -#include <86box/86box.h> +extern "C" { +# include <86box/86box.h> } // Use a triangle strip to get a quad. @@ -58,7 +57,8 @@ static float vertexData[] = { // Y up, front = CW static const int UNIFORM_DATA_SIZE = 16 * sizeof(float); -static inline VkDeviceSize aligned(VkDeviceSize v, VkDeviceSize byteAlign) +static inline VkDeviceSize +aligned(VkDeviceSize v, VkDeviceSize byteAlign) { return (v + byteAlign - 1) & ~(byteAlign - 1); } @@ -68,7 +68,8 @@ VulkanRenderer2::VulkanRenderer2(QVulkanWindow *w) { } -VkShaderModule VulkanRenderer2::createShader(const QString &name) +VkShaderModule +VulkanRenderer2::createShader(const QString &name) { QFile file(name); if (!file.open(QIODevice::ReadOnly)) { @@ -80,11 +81,11 @@ VkShaderModule VulkanRenderer2::createShader(const QString &name) VkShaderModuleCreateInfo shaderInfo; memset(&shaderInfo, 0, sizeof(shaderInfo)); - shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shaderInfo.codeSize = blob.size(); - shaderInfo.pCode = reinterpret_cast(blob.constData()); + shaderInfo.pCode = reinterpret_cast(blob.constData()); VkShaderModule shaderModule; - VkResult err = m_devFuncs->vkCreateShaderModule(m_window->device(), &shaderInfo, nullptr, &shaderModule); + VkResult err = m_devFuncs->vkCreateShaderModule(m_window->device(), &shaderInfo, nullptr, &shaderModule); if (err != VK_SUCCESS) { qWarning("Failed to create shader module: %d", err); return VK_NULL_HANDLE; @@ -93,13 +94,14 @@ VkShaderModule VulkanRenderer2::createShader(const QString &name) return shaderModule; } -bool VulkanRenderer2::createTexture() +bool +VulkanRenderer2::createTexture() { QImage img(2048, 2048, QImage::Format_RGBA8888_Premultiplied); img.fill(QColor(0, 0, 0)); - QVulkanFunctions *f = m_window->vulkanInstance()->functions(); - VkDevice dev = m_window->device(); + QVulkanFunctions *f = m_window->vulkanInstance()->functions(); + VkDevice dev = m_window->device(); m_texFormat = VK_FORMAT_B8G8R8A8_UNORM; @@ -108,7 +110,7 @@ bool VulkanRenderer2::createTexture() // tiling format. VkFormatProperties props; f->vkGetPhysicalDeviceFormatProperties(m_window->physicalDevice(), m_texFormat, &props); - const bool canSampleLinear = (props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); + const bool canSampleLinear = (props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); const bool canSampleOptimal = (props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); if (!canSampleLinear && !canSampleOptimal) { qWarning("Neither linear nor optimal image sampling is supported for RGBA8"); @@ -146,14 +148,14 @@ bool VulkanRenderer2::createTexture() VkImageViewCreateInfo viewInfo; memset(&viewInfo, 0, sizeof(viewInfo)); - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.image = m_texImage; - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.format = m_texFormat; - viewInfo.components.r = VK_COMPONENT_SWIZZLE_R; - viewInfo.components.g = VK_COMPONENT_SWIZZLE_G; - viewInfo.components.b = VK_COMPONENT_SWIZZLE_B; - viewInfo.components.a = VK_COMPONENT_SWIZZLE_A; + viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + viewInfo.image = m_texImage; + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.format = m_texFormat; + viewInfo.components.r = VK_COMPONENT_SWIZZLE_R; + viewInfo.components.g = VK_COMPONENT_SWIZZLE_G; + viewInfo.components.b = VK_COMPONENT_SWIZZLE_B; + viewInfo.components.a = VK_COMPONENT_SWIZZLE_A; viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; viewInfo.subresourceRange.levelCount = viewInfo.subresourceRange.layerCount = 1; @@ -168,24 +170,25 @@ bool VulkanRenderer2::createTexture() return true; } -bool VulkanRenderer2::createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, - VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex) +bool +VulkanRenderer2::createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, + VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex) { VkDevice dev = m_window->device(); VkImageCreateInfo imageInfo; memset(&imageInfo, 0, sizeof(imageInfo)); - imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageInfo.imageType = VK_IMAGE_TYPE_2D; - imageInfo.format = m_texFormat; - imageInfo.extent.width = size.width(); + imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.format = m_texFormat; + imageInfo.extent.width = size.width(); imageInfo.extent.height = size.height(); - imageInfo.extent.depth = 1; - imageInfo.mipLevels = 1; - imageInfo.arrayLayers = 1; - imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageInfo.tiling = tiling; - imageInfo.usage = usage; + imageInfo.extent.depth = 1; + imageInfo.mipLevels = 1; + imageInfo.arrayLayers = 1; + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.tiling = tiling; + imageInfo.usage = usage; imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; VkResult err = m_devFuncs->vkCreateImage(dev, &imageInfo, nullptr, image); @@ -230,7 +233,8 @@ bool VulkanRenderer2::createTextureImage(const QSize &size, VkImage *image, VkDe return true; } -bool VulkanRenderer2::writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory) +bool +VulkanRenderer2::writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory) { VkDevice dev = m_window->device(); @@ -242,7 +246,7 @@ bool VulkanRenderer2::writeLinearImage(const QImage &img, VkImage image, VkDevic VkSubresourceLayout layout; m_devFuncs->vkGetImageSubresourceLayout(dev, image, &subres, &layout); - uchar *p; + uchar *p; VkResult err = m_devFuncs->vkMapMemory(dev, memory, layout.offset, layout.size, 0, reinterpret_cast(&p)); if (err != VK_SUCCESS) { qWarning("Failed to map memory for linear image: %d", err); @@ -259,7 +263,8 @@ bool VulkanRenderer2::writeLinearImage(const QImage &img, VkImage image, VkDevic return true; } -void VulkanRenderer2::ensureTexture() +void +VulkanRenderer2::ensureTexture() { if (!m_texLayoutPending && !m_texStagingPending) return; @@ -269,24 +274,24 @@ void VulkanRenderer2::ensureTexture() VkImageMemoryBarrier barrier; memset(&barrier, 0, sizeof(barrier)); - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.levelCount = barrier.subresourceRange.layerCount = 1; if (m_texLayoutPending) { m_texLayoutPending = false; - barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier.image = m_texImage; + barrier.image = m_texImage; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); VkDevice dev = m_window->device(); @@ -301,38 +306,38 @@ void VulkanRenderer2::ensureTexture() VkResult err = m_devFuncs->vkMapMemory(dev, m_texMem, layout.offset, layout.size, 0, reinterpret_cast(&mappedPtr)); if (err != VK_SUCCESS) { qWarning("Failed to map memory for linear image: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } imagePitch = layout.rowPitch; - if (qobject_cast(m_window)) { - emit qobject_cast(m_window)->rendererInitialized(); + if (qobject_cast(m_window)) { + emit qobject_cast(m_window)->rendererInitialized(); } } else { m_texStagingPending = false; if (!m_texStagingTransferLayout) { - barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - barrier.image = m_texStaging; + barrier.image = m_texStaging; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); - barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; barrier.srcAccessMask = 0; barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.image = m_texImage; + barrier.image = m_texImage; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); VkDevice dev = m_window->device(); @@ -347,12 +352,12 @@ void VulkanRenderer2::ensureTexture() VkResult err = m_devFuncs->vkMapMemory(dev, m_texStagingMem, layout.offset, layout.size, 0, reinterpret_cast(&mappedPtr)); if (err != VK_SUCCESS) { qWarning("Failed to map memory for linear image: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } imagePitch = layout.rowPitch; - if (qobject_cast(m_window)) { - emit qobject_cast(m_window)->rendererInitialized(); + if (qobject_cast(m_window)) { + emit qobject_cast(m_window)->rendererInitialized(); } m_texStagingTransferLayout = true; @@ -364,26 +369,27 @@ void VulkanRenderer2::ensureTexture() copyInfo.srcSubresource.layerCount = 1; copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copyInfo.dstSubresource.layerCount = 1; - copyInfo.extent.width = m_texSize.width(); - copyInfo.extent.height = m_texSize.height(); - copyInfo.extent.depth = 1; + copyInfo.extent.width = m_texSize.width(); + copyInfo.extent.height = m_texSize.height(); + copyInfo.extent.depth = 1; m_devFuncs->vkCmdCopyImage(cb, m_texStaging, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - m_texImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Info); + m_texImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Info); - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier.image = m_texImage; + barrier.image = m_texImage; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); } } -void VulkanRenderer2::updateSamplers() +void +VulkanRenderer2::updateSamplers() { static int cur_video_filter_method = -1; @@ -400,52 +406,53 @@ void VulkanRenderer2::updateSamplers() for (int i = 0; i < m_window->concurrentFrameCount(); i++) { VkWriteDescriptorSet descWrite[2]; memset(descWrite, 0, sizeof(descWrite)); - descWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descWrite[0].dstSet = m_descSet[i]; - descWrite[0].dstBinding = 0; + descWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descWrite[0].dstSet = m_descSet[i]; + descWrite[0].dstBinding = 0; descWrite[0].descriptorCount = 1; - descWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descWrite[0].pBufferInfo = &m_uniformBufInfo[i]; + descWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descWrite[0].pBufferInfo = &m_uniformBufInfo[i]; - descWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descWrite[1].dstSet = m_descSet[i]; - descWrite[1].dstBinding = 1; + descWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descWrite[1].dstSet = m_descSet[i]; + descWrite[1].dstBinding = 1; descWrite[1].descriptorCount = 1; - descWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descWrite[1].pImageInfo = &descImageInfo; + descWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descWrite[1].pImageInfo = &descImageInfo; m_devFuncs->vkUpdateDescriptorSets(m_window->device(), 2, descWrite, 0, nullptr); } } } -void VulkanRenderer2::initResources() +void +VulkanRenderer2::initResources() { qDebug("initResources"); VkDevice dev = m_window->device(); - m_devFuncs = m_window->vulkanInstance()->deviceFunctions(dev); + m_devFuncs = m_window->vulkanInstance()->deviceFunctions(dev); // The setup is similar to hellovulkantriangle. The difference is the // presence of a second vertex attribute (texcoord), a sampler, and that we // need blending. - const int concurrentFrameCount = m_window->concurrentFrameCount(); - const VkPhysicalDeviceLimits *pdevLimits = &m_window->physicalDeviceProperties()->limits; - const VkDeviceSize uniAlign = pdevLimits->minUniformBufferOffsetAlignment; + const int concurrentFrameCount = m_window->concurrentFrameCount(); + const VkPhysicalDeviceLimits *pdevLimits = &m_window->physicalDeviceProperties()->limits; + const VkDeviceSize uniAlign = pdevLimits->minUniformBufferOffsetAlignment; qDebug("uniform buffer offset alignment is %u", (uint) uniAlign); VkBufferCreateInfo bufInfo; memset(&bufInfo, 0, sizeof(bufInfo)); bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; // Our internal layout is vertex, uniform, uniform, ... with each uniform buffer start offset aligned to uniAlign. - const VkDeviceSize vertexAllocSize = aligned(sizeof(vertexData), uniAlign); + const VkDeviceSize vertexAllocSize = aligned(sizeof(vertexData), uniAlign); const VkDeviceSize uniformAllocSize = aligned(UNIFORM_DATA_SIZE, uniAlign); - bufInfo.size = vertexAllocSize + concurrentFrameCount * uniformAllocSize; - bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + bufInfo.size = vertexAllocSize + concurrentFrameCount * uniformAllocSize; + bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; VkResult err = m_devFuncs->vkCreateBuffer(dev, &bufInfo, nullptr, &m_buf); if (err != VK_SUCCESS) { qWarning("Failed to create buffer: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } VkMemoryRequirements memReq; @@ -461,20 +468,20 @@ void VulkanRenderer2::initResources() err = m_devFuncs->vkAllocateMemory(dev, &memAllocInfo, nullptr, &m_bufMem); if (err != VK_SUCCESS) { qWarning("Failed to allocate memory: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } err = m_devFuncs->vkBindBufferMemory(dev, m_buf, m_bufMem, 0); if (err != VK_SUCCESS) { qWarning("Failed to bind buffer memory: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } quint8 *p; err = m_devFuncs->vkMapMemory(dev, m_bufMem, 0, memReq.size, 0, reinterpret_cast(&p)); if (err != VK_SUCCESS) { qWarning("Failed to map memory: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } memcpy(p, vertexData, sizeof(vertexData)); QMatrix4x4 ident; @@ -484,7 +491,7 @@ void VulkanRenderer2::initResources() memcpy(p + offset, ident.constData(), 16 * sizeof(float)); m_uniformBufInfo[i].buffer = m_buf; m_uniformBufInfo[i].offset = offset; - m_uniformBufInfo[i].range = uniformAllocSize; + m_uniformBufInfo[i].range = uniformAllocSize; } m_devFuncs->vkUnmapMemory(dev, m_bufMem); @@ -494,93 +501,86 @@ void VulkanRenderer2::initResources() VK_VERTEX_INPUT_RATE_VERTEX }; VkVertexInputAttributeDescription vertexAttrDesc[] = { - { // position - 0, // location - 0, // binding - VK_FORMAT_R32G32B32_SFLOAT, - 0 - }, + {// position + 0, // location + 0, // binding + VK_FORMAT_R32G32B32_SFLOAT, + 0 }, { // texcoord - 1, - 0, - VK_FORMAT_R32G32_SFLOAT, - 3 * sizeof(float) - } + 1, + 0, + VK_FORMAT_R32G32_SFLOAT, + 3 * sizeof(float)} }; VkPipelineVertexInputStateCreateInfo vertexInputInfo; - vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertexInputInfo.pNext = nullptr; - vertexInputInfo.flags = 0; - vertexInputInfo.vertexBindingDescriptionCount = 1; - vertexInputInfo.pVertexBindingDescriptions = &vertexBindingDesc; + vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertexInputInfo.pNext = nullptr; + vertexInputInfo.flags = 0; + vertexInputInfo.vertexBindingDescriptionCount = 1; + vertexInputInfo.pVertexBindingDescriptions = &vertexBindingDesc; vertexInputInfo.vertexAttributeDescriptionCount = 2; - vertexInputInfo.pVertexAttributeDescriptions = vertexAttrDesc; + vertexInputInfo.pVertexAttributeDescriptions = vertexAttrDesc; // Sampler. VkSamplerCreateInfo samplerInfo; memset(&samplerInfo, 0, sizeof(samplerInfo)); - samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerInfo.magFilter = VK_FILTER_NEAREST; - samplerInfo.minFilter = VK_FILTER_NEAREST; - samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.magFilter = VK_FILTER_NEAREST; + samplerInfo.minFilter = VK_FILTER_NEAREST; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samplerInfo.maxAnisotropy = 1.0f; - samplerInfo.maxLod = 0.25; - err = m_devFuncs->vkCreateSampler(dev, &samplerInfo, nullptr, &m_sampler); + samplerInfo.maxLod = 0.25; + err = m_devFuncs->vkCreateSampler(dev, &samplerInfo, nullptr, &m_sampler); if (err != VK_SUCCESS) { qWarning("Failed to create sampler: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } samplerInfo.magFilter = VK_FILTER_LINEAR; samplerInfo.minFilter = VK_FILTER_LINEAR; - err = m_devFuncs->vkCreateSampler(dev, &samplerInfo, nullptr, &m_linearSampler); + err = m_devFuncs->vkCreateSampler(dev, &samplerInfo, nullptr, &m_linearSampler); if (err != VK_SUCCESS) { qWarning("Failed to create sampler: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } // Texture. if (!createTexture()) { qWarning("Failed to create texture"); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } // Set up descriptor set and its layout. VkDescriptorPoolSize descPoolSizes[2] = { - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uint32_t(concurrentFrameCount) }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, uint32_t(concurrentFrameCount) } + {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uint32_t(concurrentFrameCount)}, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, uint32_t(concurrentFrameCount)} }; VkDescriptorPoolCreateInfo descPoolInfo; memset(&descPoolInfo, 0, sizeof(descPoolInfo)); - descPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - descPoolInfo.maxSets = concurrentFrameCount; + descPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descPoolInfo.maxSets = concurrentFrameCount; descPoolInfo.poolSizeCount = 2; - descPoolInfo.pPoolSizes = descPoolSizes; - err = m_devFuncs->vkCreateDescriptorPool(dev, &descPoolInfo, nullptr, &m_descPool); + descPoolInfo.pPoolSizes = descPoolSizes; + err = m_devFuncs->vkCreateDescriptorPool(dev, &descPoolInfo, nullptr, &m_descPool); if (err != VK_SUCCESS) { qWarning("Failed to create descriptor pool: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } - VkDescriptorSetLayoutBinding layoutBinding[2] = - { - { - 0, // binding - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 1, // descriptorCount - VK_SHADER_STAGE_VERTEX_BIT, - nullptr - }, - { - 1, // binding - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, // descriptorCount - VK_SHADER_STAGE_FRAGMENT_BIT, - nullptr - } + VkDescriptorSetLayoutBinding layoutBinding[2] = { + {0, // binding + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 1, // descriptorCount + VK_SHADER_STAGE_VERTEX_BIT, + nullptr}, + { 1, // binding + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + 1, // descriptorCount + VK_SHADER_STAGE_FRAGMENT_BIT, + nullptr} }; VkDescriptorSetLayoutCreateInfo descLayoutInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, @@ -592,7 +592,7 @@ void VulkanRenderer2::initResources() err = m_devFuncs->vkCreateDescriptorSetLayout(dev, &descLayoutInfo, nullptr, &m_descSetLayout); if (err != VK_SUCCESS) { qWarning("Failed to create descriptor set layout: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } for (int i = 0; i < concurrentFrameCount; ++i) { @@ -606,17 +606,17 @@ void VulkanRenderer2::initResources() err = m_devFuncs->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_descSet[i]); if (err != VK_SUCCESS) { qWarning("Failed to allocate descriptor set: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } VkWriteDescriptorSet descWrite[2]; memset(descWrite, 0, sizeof(descWrite)); - descWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descWrite[0].dstSet = m_descSet[i]; - descWrite[0].dstBinding = 0; + descWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descWrite[0].dstSet = m_descSet[i]; + descWrite[0].dstBinding = 0; descWrite[0].descriptorCount = 1; - descWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descWrite[0].pBufferInfo = &m_uniformBufInfo[i]; + descWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descWrite[0].pBufferInfo = &m_uniformBufInfo[i]; VkDescriptorImageInfo descImageInfo = { video_filter_method == 1 ? m_linearSampler : m_sampler, @@ -624,12 +624,12 @@ void VulkanRenderer2::initResources() VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }; - descWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descWrite[1].dstSet = m_descSet[i]; - descWrite[1].dstBinding = 1; + descWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descWrite[1].dstSet = m_descSet[i]; + descWrite[1].dstBinding = 1; descWrite[1].descriptorCount = 1; - descWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descWrite[1].pImageInfo = &descImageInfo; + descWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descWrite[1].pImageInfo = &descImageInfo; m_devFuncs->vkUpdateDescriptorSets(dev, 2, descWrite, 0, nullptr); } @@ -638,60 +638,60 @@ void VulkanRenderer2::initResources() VkPipelineCacheCreateInfo pipelineCacheInfo; memset(&pipelineCacheInfo, 0, sizeof(pipelineCacheInfo)); pipelineCacheInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - err = m_devFuncs->vkCreatePipelineCache(dev, &pipelineCacheInfo, nullptr, &m_pipelineCache); + err = m_devFuncs->vkCreatePipelineCache(dev, &pipelineCacheInfo, nullptr, &m_pipelineCache); if (err != VK_SUCCESS) { qWarning("Failed to create pipeline cache: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } // Pipeline layout VkPipelineLayoutCreateInfo pipelineLayoutInfo; memset(&pipelineLayoutInfo, 0, sizeof(pipelineLayoutInfo)); - pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo.setLayoutCount = 1; - pipelineLayoutInfo.pSetLayouts = &m_descSetLayout; - err = m_devFuncs->vkCreatePipelineLayout(dev, &pipelineLayoutInfo, nullptr, &m_pipelineLayout); + pipelineLayoutInfo.pSetLayouts = &m_descSetLayout; + err = m_devFuncs->vkCreatePipelineLayout(dev, &pipelineLayoutInfo, nullptr, &m_pipelineLayout); if (err != VK_SUCCESS) { qWarning("Failed to create pipeline layout: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } // Shaders -/* -#version 440 + /* + #version 440 -layout(location = 0) in vec4 position; -layout(location = 1) in vec2 texcoord; + layout(location = 0) in vec4 position; + layout(location = 1) in vec2 texcoord; -layout(location = 0) out vec2 v_texcoord; + layout(location = 0) out vec2 v_texcoord; -layout(std140, binding = 0) uniform buf { - mat4 mvp; -} ubuf; + layout(std140, binding = 0) uniform buf { + mat4 mvp; + } ubuf; -out gl_PerVertex { vec4 gl_Position; }; + out gl_PerVertex { vec4 gl_Position; }; -void main() -{ - v_texcoord = texcoord; - gl_Position = ubuf.mvp * position; -} -*/ + void main() + { + v_texcoord = texcoord; + gl_Position = ubuf.mvp * position; + } + */ VkShaderModule vertShaderModule = createShader(QStringLiteral(":/texture_vert.spv")); -/* -#version 440 + /* + #version 440 -layout(location = 0) in vec2 v_texcoord; + layout(location = 0) in vec2 v_texcoord; -layout(location = 0) out vec4 fragColor; + layout(location = 0) out vec4 fragColor; -layout(binding = 1) uniform sampler2D tex; + layout(binding = 1) uniform sampler2D tex; -void main() -{ - fragColor = texture(tex, v_texcoord); -} -*/ + void main() + { + fragColor = texture(tex, v_texcoord); + } + */ VkShaderModule fragShaderModule = createShader(QStringLiteral(":/texture_frag.spv")); // Graphics pipeline @@ -720,46 +720,46 @@ void main() } }; pipelineInfo.stageCount = 2; - pipelineInfo.pStages = shaderStages; + pipelineInfo.pStages = shaderStages; pipelineInfo.pVertexInputState = &vertexInputInfo; VkPipelineInputAssemblyStateCreateInfo ia; memset(&ia, 0, sizeof(ia)); - ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; pipelineInfo.pInputAssemblyState = &ia; // The viewport and scissor will be set dynamically via vkCmdSetViewport/Scissor. // This way the pipeline does not need to be touched when resizing the window. VkPipelineViewportStateCreateInfo vp; memset(&vp, 0, sizeof(vp)); - vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - vp.viewportCount = 1; - vp.scissorCount = 1; + vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + vp.viewportCount = 1; + vp.scissorCount = 1; pipelineInfo.pViewportState = &vp; VkPipelineRasterizationStateCreateInfo rs; memset(&rs, 0, sizeof(rs)); - rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rs.polygonMode = VK_POLYGON_MODE_FILL; - rs.cullMode = VK_CULL_MODE_BACK_BIT; - rs.frontFace = VK_FRONT_FACE_CLOCKWISE; - rs.lineWidth = 1.0f; + rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rs.polygonMode = VK_POLYGON_MODE_FILL; + rs.cullMode = VK_CULL_MODE_BACK_BIT; + rs.frontFace = VK_FRONT_FACE_CLOCKWISE; + rs.lineWidth = 1.0f; pipelineInfo.pRasterizationState = &rs; VkPipelineMultisampleStateCreateInfo ms; memset(&ms, 0, sizeof(ms)); - ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; pipelineInfo.pMultisampleState = &ms; VkPipelineDepthStencilStateCreateInfo ds; memset(&ds, 0, sizeof(ds)); - ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - ds.depthTestEnable = VK_TRUE; - ds.depthWriteEnable = VK_TRUE; - ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + ds.depthTestEnable = VK_TRUE; + ds.depthWriteEnable = VK_TRUE; + ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; pipelineInfo.pDepthStencilState = &ds; VkPipelineColorBlendStateCreateInfo cb; @@ -768,33 +768,33 @@ void main() // assume pre-multiplied alpha, blend, write out all of rgba VkPipelineColorBlendAttachmentState att; memset(&att, 0, sizeof(att)); - att.colorWriteMask = 0xF; - att.blendEnable = VK_TRUE; - att.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - att.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - att.colorBlendOp = VK_BLEND_OP_ADD; - att.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - att.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - att.alphaBlendOp = VK_BLEND_OP_ADD; - cb.attachmentCount = 1; - cb.pAttachments = &att; + att.colorWriteMask = 0xF; + att.blendEnable = VK_TRUE; + att.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; + att.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + att.colorBlendOp = VK_BLEND_OP_ADD; + att.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + att.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + att.alphaBlendOp = VK_BLEND_OP_ADD; + cb.attachmentCount = 1; + cb.pAttachments = &att; pipelineInfo.pColorBlendState = &cb; - VkDynamicState dynEnable[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkDynamicState dynEnable[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dyn; memset(&dyn, 0, sizeof(dyn)); - dyn.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dyn.dynamicStateCount = sizeof(dynEnable) / sizeof(VkDynamicState); - dyn.pDynamicStates = dynEnable; + dyn.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dyn.dynamicStateCount = sizeof(dynEnable) / sizeof(VkDynamicState); + dyn.pDynamicStates = dynEnable; pipelineInfo.pDynamicState = &dyn; - pipelineInfo.layout = m_pipelineLayout; + pipelineInfo.layout = m_pipelineLayout; pipelineInfo.renderPass = m_window->defaultRenderPass(); err = m_devFuncs->vkCreateGraphicsPipelines(dev, m_pipelineCache, 1, &pipelineInfo, nullptr, &m_pipeline); if (err != VK_SUCCESS) { qWarning("Failed to create graphics pipeline: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } if (vertShaderModule) @@ -807,7 +807,8 @@ void main() pclog("Vulkan driver version: %d.%d.%d\n", VK_VERSION_MAJOR(m_window->physicalDeviceProperties()->driverVersion), VK_VERSION_MINOR(m_window->physicalDeviceProperties()->driverVersion), VK_VERSION_PATCH(m_window->physicalDeviceProperties()->driverVersion)); } -void VulkanRenderer2::initSwapChainResources() +void +VulkanRenderer2::initSwapChainResources() { qDebug("initSwapChainResources"); @@ -815,12 +816,14 @@ void VulkanRenderer2::initSwapChainResources() m_proj = m_window->clipCorrectionMatrix(); // adjust for Vulkan-OpenGL clip space differences } -void VulkanRenderer2::releaseSwapChainResources() +void +VulkanRenderer2::releaseSwapChainResources() { qDebug("releaseSwapChainResources"); } -void VulkanRenderer2::releaseResources() +void +VulkanRenderer2::releaseResources() { qDebug("releaseResources"); @@ -897,85 +900,88 @@ void VulkanRenderer2::releaseResources() } } -void VulkanRenderer2::startNextFrame() +void +VulkanRenderer2::startNextFrame() { - VkDevice dev = m_window->device(); - VkCommandBuffer cb = m_window->currentCommandBuffer(); - const QSize sz = m_window->swapChainImageSize(); + VkDevice dev = m_window->device(); + VkCommandBuffer cb = m_window->currentCommandBuffer(); + const QSize sz = m_window->swapChainImageSize(); updateSamplers(); // Add the necessary barriers and do the host-linear -> device-optimal copy, if not yet done. ensureTexture(); - VkClearColorValue clearColor = {{ 0, 0, 0, 1 }}; + VkClearColorValue clearColor = { + {0, 0, 0, 1} + }; VkClearDepthStencilValue clearDS = { 1, 0 }; - VkClearValue clearValues[2]; + VkClearValue clearValues[2]; memset(clearValues, 0, sizeof(clearValues)); - clearValues[0].color = clearColor; + clearValues[0].color = clearColor; clearValues[1].depthStencil = clearDS; VkRenderPassBeginInfo rpBeginInfo; memset(&rpBeginInfo, 0, sizeof(rpBeginInfo)); - rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - rpBeginInfo.renderPass = m_window->defaultRenderPass(); - rpBeginInfo.framebuffer = m_window->currentFramebuffer(); - rpBeginInfo.renderArea.extent.width = sz.width(); + rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + rpBeginInfo.renderPass = m_window->defaultRenderPass(); + rpBeginInfo.framebuffer = m_window->currentFramebuffer(); + rpBeginInfo.renderArea.extent.width = sz.width(); rpBeginInfo.renderArea.extent.height = sz.height(); - rpBeginInfo.clearValueCount = 2; - rpBeginInfo.pClearValues = clearValues; - VkCommandBuffer cmdBuf = m_window->currentCommandBuffer(); + rpBeginInfo.clearValueCount = 2; + rpBeginInfo.pClearValues = clearValues; + VkCommandBuffer cmdBuf = m_window->currentCommandBuffer(); m_devFuncs->vkCmdBeginRenderPass(cmdBuf, &rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - quint8 *p; + quint8 *p; VkResult err = m_devFuncs->vkMapMemory(dev, m_bufMem, m_uniformBufInfo[m_window->currentFrame()].offset, - UNIFORM_DATA_SIZE, 0, reinterpret_cast(&p)); + UNIFORM_DATA_SIZE, 0, reinterpret_cast(&p)); if (err != VK_SUCCESS) qFatal("Failed to map memory: %d", err); QMatrix4x4 m = m_proj; - //m.rotate(m_rotation, 0, 0, 1); + // m.rotate(m_rotation, 0, 0, 1); memcpy(p, m.constData(), 16 * sizeof(float)); m_devFuncs->vkUnmapMemory(dev, m_bufMem); p = nullptr; // Second pass for texture coordinates. err = m_devFuncs->vkMapMemory(dev, m_bufMem, 0, - sizeof(vertexData), 0, reinterpret_cast(&p)); + sizeof(vertexData), 0, reinterpret_cast(&p)); if (err != VK_SUCCESS) qFatal("Failed to map memory: %d", err); - float* floatData = (float*)p; - auto source = qobject_cast(m_window)->source; - auto destination = qobject_cast(m_window)->destination; - floatData[3] = (float)source.x() / 2048.f; - floatData[9] = (float)(source.y()) / 2048.f; - floatData[8] = (float)source.x() / 2048.f; - floatData[4] = (float)(source.y() + source.height()) / 2048.f; - floatData[13] = (float)(source.x() + source.width()) / 2048.f; - floatData[19] = (float)(source.y()) / 2048.f; - floatData[18] = (float)(source.x() + source.width()) / 2048.f; - floatData[14] = (float)(source.y() + source.height()) / 2048.f; + float *floatData = (float *) p; + auto source = qobject_cast(m_window)->source; + auto destination = qobject_cast(m_window)->destination; + floatData[3] = (float) source.x() / 2048.f; + floatData[9] = (float) (source.y()) / 2048.f; + floatData[8] = (float) source.x() / 2048.f; + floatData[4] = (float) (source.y() + source.height()) / 2048.f; + floatData[13] = (float) (source.x() + source.width()) / 2048.f; + floatData[19] = (float) (source.y()) / 2048.f; + floatData[18] = (float) (source.x() + source.width()) / 2048.f; + floatData[14] = (float) (source.y() + source.height()) / 2048.f; m_devFuncs->vkUnmapMemory(dev, m_bufMem); m_devFuncs->vkCmdBindPipeline(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline); m_devFuncs->vkCmdBindDescriptorSets(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, - &m_descSet[m_window->currentFrame()], 0, nullptr); + &m_descSet[m_window->currentFrame()], 0, nullptr); VkDeviceSize vbOffset = 0; m_devFuncs->vkCmdBindVertexBuffers(cb, 0, 1, &m_buf, &vbOffset); VkViewport viewport; - viewport.x = destination.x() * m_window->devicePixelRatio(); - viewport.y = destination.y() * m_window->devicePixelRatio(); - viewport.width = destination.width() * m_window->devicePixelRatio(); - viewport.height = destination.height() * m_window->devicePixelRatio(); + viewport.x = destination.x() * m_window->devicePixelRatio(); + viewport.y = destination.y() * m_window->devicePixelRatio(); + viewport.width = destination.width() * m_window->devicePixelRatio(); + viewport.height = destination.height() * m_window->devicePixelRatio(); viewport.minDepth = 0; viewport.maxDepth = 1; m_devFuncs->vkCmdSetViewport(cb, 0, 1, &viewport); VkRect2D scissor; - scissor.offset.x = viewport.x; - scissor.offset.y = viewport.y; - scissor.extent.width = viewport.width; + scissor.offset.x = viewport.x; + scissor.offset.y = viewport.y; + scissor.extent.width = viewport.width; scissor.extent.height = viewport.height; m_devFuncs->vkCmdSetScissor(cb, 0, 1, &scissor); @@ -984,20 +990,20 @@ void VulkanRenderer2::startNextFrame() m_devFuncs->vkCmdEndRenderPass(cmdBuf); if (m_texStagingTransferLayout) { - VkImageMemoryBarrier barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + VkImageMemoryBarrier barrier {}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.levelCount = barrier.subresourceRange.layerCount = 1; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier.image = m_texImage; + barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + barrier.image = m_texImage; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); m_texStagingPending = true; } diff --git a/src/qt/qt_vulkanrenderer.hpp b/src/qt/qt_vulkanrenderer.hpp index abd4d7a13..7961dd7f9 100644 --- a/src/qt/qt_vulkanrenderer.hpp +++ b/src/qt/qt_vulkanrenderer.hpp @@ -36,12 +36,11 @@ #include #if QT_CONFIG(vulkan) -#include "qt_vulkanwindowrenderer.hpp" +# include "qt_vulkanwindowrenderer.hpp" -class VulkanRenderer2 : public QVulkanWindowRenderer -{ +class VulkanRenderer2 : public QVulkanWindowRenderer { public: - void* mappedPtr = nullptr; + void *mappedPtr = nullptr; size_t imagePitch = 2048 * 4; VulkanRenderer2(QVulkanWindow *w); @@ -54,42 +53,42 @@ public: private: VkShaderModule createShader(const QString &name); - bool createTexture(); - bool createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, - VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex); - bool writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory); - void ensureTexture(); - void updateSamplers(); + bool createTexture(); + bool createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, + VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex); + bool writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory); + void ensureTexture(); + void updateSamplers(); - QVulkanWindow *m_window; + QVulkanWindow *m_window; QVulkanDeviceFunctions *m_devFuncs; - VkDeviceMemory m_bufMem = VK_NULL_HANDLE; - VkBuffer m_buf = VK_NULL_HANDLE; + VkDeviceMemory m_bufMem = VK_NULL_HANDLE; + VkBuffer m_buf = VK_NULL_HANDLE; VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - VkDescriptorPool m_descPool = VK_NULL_HANDLE; + VkDescriptorPool m_descPool = VK_NULL_HANDLE; VkDescriptorSetLayout m_descSetLayout = VK_NULL_HANDLE; - VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; + VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - VkPipelineCache m_pipelineCache = VK_NULL_HANDLE; + VkPipelineCache m_pipelineCache = VK_NULL_HANDLE; VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; - VkPipeline m_pipeline = VK_NULL_HANDLE; + VkPipeline m_pipeline = VK_NULL_HANDLE; - VkSampler m_sampler = VK_NULL_HANDLE; - VkSampler m_linearSampler = VK_NULL_HANDLE; - VkImage m_texImage = VK_NULL_HANDLE; - VkDeviceMemory m_texMem = VK_NULL_HANDLE; - bool m_texLayoutPending = false; - VkImageView m_texView = VK_NULL_HANDLE; - VkImage m_texStaging = VK_NULL_HANDLE; - VkDeviceMemory m_texStagingMem = VK_NULL_HANDLE; - bool m_texStagingPending = false; - bool m_texStagingTransferLayout = false; - QSize m_texSize; - VkFormat m_texFormat; + VkSampler m_sampler = VK_NULL_HANDLE; + VkSampler m_linearSampler = VK_NULL_HANDLE; + VkImage m_texImage = VK_NULL_HANDLE; + VkDeviceMemory m_texMem = VK_NULL_HANDLE; + bool m_texLayoutPending = false; + VkImageView m_texView = VK_NULL_HANDLE; + VkImage m_texStaging = VK_NULL_HANDLE; + VkDeviceMemory m_texStagingMem = VK_NULL_HANDLE; + bool m_texStagingPending = false; + bool m_texStagingTransferLayout = false; + QSize m_texSize; + VkFormat m_texFormat; QMatrix4x4 m_proj; - float m_rotation = 0.0f; + float m_rotation = 0.0f; }; #endif diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index ba32d6e9b..60ad5be96 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -4,20 +4,19 @@ #include #if QT_CONFIG(vulkan) -#include -#include -#include -#include +# include +# include +# include +# include -#include "qt_mainwindow.hpp" -#include "qt_vulkanrenderer.hpp" +# include "qt_mainwindow.hpp" +# include "qt_vulkanrenderer.hpp" -extern "C" -{ -#include <86box/86box.h> -#include <86box/video.h> +extern "C" { +# include <86box/86box.h> +# include <86box/video.h> } -#if 0 +# if 0 extern MainWindow* main_window; /* #version 450 @@ -695,10 +694,10 @@ public: return "VK_ERROR_VALIDATION_FAILED_EXT"; case VK_ERROR_INVALID_SHADER_NV: return "VK_ERROR_INVALID_SHADER_NV"; -#if VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162 +# if VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162 case VK_ERROR_INCOMPATIBLE_VERSION_KHR: return "VK_ERROR_INCOMPATIBLE_VERSION_KHR"; -#endif +# endif case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; case VK_ERROR_NOT_PERMITTED_EXT: @@ -789,9 +788,9 @@ public: m_devFuncs->vkDeviceWaitIdle(m_window->device()); } }; -#endif +# endif -VulkanWindowRenderer::VulkanWindowRenderer(QWidget* parent) +VulkanWindowRenderer::VulkanWindowRenderer(QWidget *parent) : QVulkanWindow(parent->windowHandle()) { parentWidget = parent; @@ -799,47 +798,57 @@ VulkanWindowRenderer::VulkanWindowRenderer(QWidget* parent) instance.create(); setVulkanInstance(&instance); setPhysicalDeviceIndex(0); - setPreferredColorFormats({VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A8B8G8R8_UNORM_PACK32}); + setPreferredColorFormats({ VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A8B8G8R8_UNORM_PACK32 }); setFlags(Flag::PersistentResources); buf_usage = std::vector(1); buf_usage[0].clear(); } -QVulkanWindowRenderer* VulkanWindowRenderer::createRenderer() +QVulkanWindowRenderer * +VulkanWindowRenderer::createRenderer() { renderer = new VulkanRenderer2(this); return renderer; } -void VulkanWindowRenderer::resizeEvent(QResizeEvent *event) { +void +VulkanWindowRenderer::resizeEvent(QResizeEvent *event) +{ onResize(width(), height()); QVulkanWindow::resizeEvent(event); } -bool VulkanWindowRenderer::event(QEvent *event) +bool +VulkanWindowRenderer::event(QEvent *event) { bool res = false; - if (!eventDelegate(event, res)) return QVulkanWindow::event(event); + if (!eventDelegate(event, res)) + return QVulkanWindow::event(event); return res; } -void VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) +void +VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { auto origSource = source; source.setRect(x, y, w, h); - if (isExposed()) requestUpdate(); + if (isExposed()) + requestUpdate(); buf_usage[0].clear(); - if (origSource != source) onResize(this->width(), this->height()); + if (origSource != source) + onResize(this->width(), this->height()); } -uint32_t VulkanWindowRenderer::getBytesPerRow() +uint32_t +VulkanWindowRenderer::getBytesPerRow() { return renderer->imagePitch; } -std::vector> VulkanWindowRenderer::getBuffers() +std::vector> +VulkanWindowRenderer::getBuffers() { - return std::vector{std::make_tuple((uint8_t*)renderer->mappedPtr, &this->buf_usage[0])}; + return std::vector { std::make_tuple((uint8_t *) renderer->mappedPtr, &this->buf_usage[0]) }; } #endif diff --git a/src/qt/qt_vulkanwindowrenderer.hpp b/src/qt/qt_vulkanwindowrenderer.hpp index df252d393..828d091e6 100644 --- a/src/qt/qt_vulkanwindowrenderer.hpp +++ b/src/qt/qt_vulkanwindowrenderer.hpp @@ -4,35 +4,36 @@ #include #if QT_CONFIG(vulkan) -#include "qt_renderercommon.hpp" -#include "qt_vulkanrenderer.hpp" +# include "qt_renderercommon.hpp" +# include "qt_vulkanrenderer.hpp" class VulkanRenderer2; -class VulkanWindowRenderer : public QVulkanWindow, public RendererCommon -{ +class VulkanWindowRenderer : public QVulkanWindow, public RendererCommon { Q_OBJECT public: - VulkanWindowRenderer(QWidget* parent); + VulkanWindowRenderer(QWidget *parent); public slots: void onBlit(int buf_idx, int x, int y, int w, int h); signals: void rendererInitialized(); void errorInitializing(); + protected: virtual std::vector> getBuffers() override; - void resizeEvent(QResizeEvent*) override; - bool event(QEvent*) override; - uint32_t getBytesPerRow() override; + void resizeEvent(QResizeEvent *) override; + bool event(QEvent *) override; + uint32_t getBytesPerRow() override; + private: QVulkanInstance instance; - QVulkanWindowRenderer* createRenderer() override; + QVulkanWindowRenderer *createRenderer() override; friend class VulkanRendererEmu; friend class VulkanRenderer2; - VulkanRenderer2* renderer; + VulkanRenderer2 *renderer; }; #endif diff --git a/src/qt/qt_winmanagerfilter.cpp b/src/qt/qt_winmanagerfilter.cpp index 2c6053839..d9a6208b1 100644 --- a/src/qt/qt_winmanagerfilter.cpp +++ b/src/qt/qt_winmanagerfilter.cpp @@ -19,14 +19,13 @@ #include #include <86box/win.h> -bool WindowsManagerFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) +bool +WindowsManagerFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) { - if (eventType == "windows_generic_MSG") - { + if (eventType == "windows_generic_MSG") { MSG *msg = static_cast(message); - switch (msg->message) - { + switch (msg->message) { case WM_SHOWSETTINGS: emit showsettings(); return true; @@ -51,14 +50,12 @@ bool WindowsManagerFilter::nativeEventFilter(const QByteArray &eventType, void * return false; } -bool WindowsManagerFilter::eventFilter(QObject *obj, QEvent *event) +bool +WindowsManagerFilter::eventFilter(QObject *obj, QEvent *event) { - if (event->type() == QEvent::WindowBlocked) - { + if (event->type() == QEvent::WindowBlocked) { emit dialogstatus(1); - } - else if (event->type() == QEvent::WindowUnblocked) - { + } else if (event->type() == QEvent::WindowUnblocked) { emit dialogstatus(0); } diff --git a/src/qt/qt_winmanagerfilter.hpp b/src/qt/qt_winmanagerfilter.hpp index d715d9322..cd141e93f 100644 --- a/src/qt/qt_winmanagerfilter.hpp +++ b/src/qt/qt_winmanagerfilter.hpp @@ -23,17 +23,16 @@ #include #if QT_VERSION_MAJOR >= 6 -#define result_t qintptr +# define result_t qintptr #else -#define result_t long +# define result_t long #endif /* * Filters native events for messages from VM-manager and * window blocked events to notify about open modal dialogs. */ -class WindowsManagerFilter : public QObject, public QAbstractNativeEventFilter -{ +class WindowsManagerFilter : public QObject, public QAbstractNativeEventFilter { Q_OBJECT public: diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index e798093c0..56d8c9ec9 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -45,24 +45,20 @@ #include extern "C" void win_joystick_handle(PRAWINPUT); -std::unique_ptr WindowsRawInputFilter::Register(QMainWindow *window) +std::unique_ptr +WindowsRawInputFilter::Register(QMainWindow *window) { - HWND wnd = (HWND)window->winId(); + HWND wnd = (HWND) window->winId(); - RAWINPUTDEVICE rid[2] = - { - { - .usUsagePage = 0x01, - .usUsage = 0x06, - .dwFlags = RIDEV_NOHOTKEYS, - .hwndTarget = wnd - }, - { - .usUsagePage = 0x01, - .usUsage = 0x02, - .dwFlags = 0, - .hwndTarget = wnd - } + RAWINPUTDEVICE rid[2] = { + {.usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_NOHOTKEYS, + .hwndTarget = wnd}, + { .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = 0, + .hwndTarget = wnd} }; if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) @@ -77,8 +73,7 @@ WindowsRawInputFilter::WindowsRawInputFilter(QMainWindow *window) { this->window = window; - for (auto menu : window->findChildren()) - { + for (auto menu : window->findChildren()) { connect(menu, &QMenu::aboutToShow, this, [=]() { menus_open++; }); connect(menu, &QMenu::aboutToHide, this, [=]() { menus_open--; }); } @@ -91,29 +86,24 @@ WindowsRawInputFilter::WindowsRawInputFilter(QMainWindow *window) WindowsRawInputFilter::~WindowsRawInputFilter() { - RAWINPUTDEVICE rid[2] = - { - { - .usUsagePage = 0x01, - .usUsage = 0x06, - .dwFlags = RIDEV_REMOVE, - .hwndTarget = NULL - }, - { - .usUsagePage = 0x01, - .usUsage = 0x02, - .dwFlags = RIDEV_REMOVE, - .hwndTarget = NULL - } + RAWINPUTDEVICE rid[2] = { + {.usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_REMOVE, + .hwndTarget = NULL}, + { .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = RIDEV_REMOVE, + .hwndTarget = NULL} }; RegisterRawInputDevices(rid, 2, sizeof(rid[0])); } -bool WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) +bool +WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) { - if (eventType == "windows_generic_MSG") - { + if (eventType == "windows_generic_MSG") { MSG *msg = static_cast(message); if (msg->message == WM_INPUT) { @@ -134,7 +124,8 @@ bool WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void return false; } -void WindowsRawInputFilter::handle_input(HRAWINPUT input) +void +WindowsRawInputFilter::handle_input(HRAWINPUT input) { UINT size = 0; @@ -142,12 +133,10 @@ void WindowsRawInputFilter::handle_input(HRAWINPUT input) std::vector buf(size); - if (GetRawInputData(input, RID_INPUT, buf.data(), &size, sizeof(RAWINPUTHEADER)) == size) - { - PRAWINPUT raw = (PRAWINPUT)buf.data(); + if (GetRawInputData(input, RID_INPUT, buf.data(), &size, sizeof(RAWINPUTHEADER)) == size) { + PRAWINPUT raw = (PRAWINPUT) buf.data(); - switch(raw->header.dwType) - { + switch (raw->header.dwType) { case RIM_TYPEKEYBOARD: keyboard_handle(raw); break; @@ -156,30 +145,30 @@ void WindowsRawInputFilter::handle_input(HRAWINPUT input) mouse_handle(raw); break; case RIM_TYPEHID: - { - win_joystick_handle(raw); - break; - } + { + win_joystick_handle(raw); + break; + } } } } /* The following is more or less a direct copy of the old WIN32 implementation */ -void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) +void +WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) { - USHORT scancode; + USHORT scancode; static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0; RAWKEYBOARD rawKB = raw->data.keyboard; - scancode = rawKB.MakeCode; + scancode = rawKB.MakeCode; if (kbd_req_capture && !mouse_capture) return; /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) - { + if (!(rawKB.Flags & RI_KEY_E1)) { if (rawKB.Flags & RI_KEY_E0) scancode |= 0x100; @@ -196,15 +185,10 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) We use scan code 0xFFFF to mean a mapping that has a prefix other than E0 and that is not E1 1D, which is, for our purposes, invalid. */ - if ((scancode == 0x00F) && - !(rawKB.Flags & RI_KEY_BREAK) && - (recv_lalt || recv_ralt) && - !mouse_capture) - { + if ((scancode == 0x00F) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && !mouse_capture) { /* We received a TAB while ALT was pressed, while the mouse is not captured, suppress the TAB and send an ALT key up. */ - if (recv_lalt) - { + if (recv_lalt) { keyboard_input(0, 0x038); /* Extra key press and release so the guest is not stuck in the menu bar. */ @@ -212,8 +196,7 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) keyboard_input(0, 0x038); recv_lalt = 0; } - if (recv_ralt) - { + if (recv_ralt) { keyboard_input(0, 0x138); /* Extra key press and release so the guest is not stuck in the menu bar. */ @@ -221,30 +204,22 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) keyboard_input(0, 0x138); recv_ralt = 0; } - } - else if (((scancode == 0x038) || (scancode == 0x138)) && - !(rawKB.Flags & RI_KEY_BREAK) && - recv_tab && - !mouse_capture) - { + } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && !mouse_capture) { /* We received an ALT while TAB was pressed, while the mouse is not captured, suppress the ALT and send a TAB key up. */ keyboard_input(0, 0x00F); recv_tab = 0; - } - else - { - switch (scancode) - { - case 0x00F: - recv_tab = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x038: - recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x138: - recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); - break; + } else { + switch (scancode) { + case 0x00F: + recv_tab = !(rawKB.Flags & RI_KEY_BREAK); + break; + case 0x038: + recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); + break; + case 0x138: + recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); + break; } /* Translate right CTRL to left ALT if the user has so @@ -257,18 +232,14 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) if (scancode != 0xFFFF) keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); } - } - else - { - if (rawKB.MakeCode == 0x1D) - { + } else { + if (rawKB.MakeCode == 0x1D) { scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would otherwise be E0 00 but that is invalid anyway). Also, take a potential mapping into account. */ - } - else + } else scancode = 0xFFFF; if (scancode != 0xFFFF) keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); @@ -277,7 +248,8 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) /* This is so we can disambiguate scan codes that would otherwise conflict and get passed on incorrectly. */ -UINT16 WindowsRawInputFilter::convert_scan_code(UINT16 scan_code) +UINT16 +WindowsRawInputFilter::convert_scan_code(UINT16 scan_code) { if ((scan_code & 0xff00) == 0xe000) scan_code = (scan_code & 0xff) | 0x0100; @@ -293,19 +265,20 @@ UINT16 WindowsRawInputFilter::convert_scan_code(UINT16 scan_code) return scan_code; } -void WindowsRawInputFilter::keyboard_getkeymap() +void +WindowsRawInputFilter::keyboard_getkeymap() { - const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - const LPCSTR valueName = "Scancode Map"; + const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + const LPCSTR valueName = "Scancode Map"; unsigned char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; - UINT32 *bufEx2; - int scMapCount; - UINT16 *bufEx; - int scancode_unmapped; - int scancode_mapped; + DWORD bufSize; + HKEY hKey; + int j; + UINT32 *bufEx2; + int scMapCount; + UINT16 *bufEx; + int scancode_unmapped; + int scancode_mapped; /* First, prepare the default scan code map list which is 1:1. * Remappings will be inserted directly into it. @@ -318,24 +291,20 @@ void WindowsRawInputFilter::keyboard_getkeymap() /* Get the scan code remappings from: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ bufSize = 32768; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) - { - if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) - { - bufEx2 = (UINT32 *)buf; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { + bufEx2 = (UINT32 *) buf; scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) - { - bufEx = (UINT16 *)(buf + 12); - for (j = 0; j < scMapCount * 2; j += 2) - { + if ((bufSize != 0) && (scMapCount != 0)) { + bufEx = (UINT16 *) (buf + 12); + for (j = 0; j < scMapCount * 2; j += 2) { /* Each scan code is 32-bit: 16 bits of remapped scan code, and 16 bits of original scan code. */ scancode_unmapped = bufEx[j + 1]; - scancode_mapped = bufEx[j]; + scancode_mapped = bufEx[j]; scancode_unmapped = convert_scan_code(scancode_unmapped); - scancode_mapped = convert_scan_code(scancode_mapped); + scancode_mapped = convert_scan_code(scancode_mapped); /* Ignore source scan codes with prefixes other than E1 that are not E1 1D. */ @@ -348,9 +317,10 @@ void WindowsRawInputFilter::keyboard_getkeymap() } } -void WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) +void +WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) { - RAWMOUSE state = raw->data.mouse; + RAWMOUSE state = raw->data.mouse; static int x, y; /* read mouse buttons and wheel */ @@ -369,13 +339,11 @@ void WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) buttons &= ~2; - if (state.usButtonFlags & RI_MOUSE_WHEEL) - { - dwheel += (SHORT)state.usButtonData / 120; + if (state.usButtonFlags & RI_MOUSE_WHEEL) { + dwheel += (SHORT) state.usButtonData / 120; } - if (state.usFlags & MOUSE_MOVE_ABSOLUTE) - { + if (state.usFlags & MOUSE_MOVE_ABSOLUTE) { /* absolute mouse, i.e. RDP or VNC * seems to work fine for RDP on Windows 10 * Not sure about other environments. @@ -384,46 +352,42 @@ void WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) dy += (state.lLastY - y) / 25; x = state.lLastX; y = state.lLastY; - } - else - { + } else { /* relative mouse, i.e. regular mouse */ dx += state.lLastX; dy += state.lLastY; } - HWND wnd = (HWND)window->winId(); + HWND wnd = (HWND) window->winId(); RECT rect; GetWindowRect(wnd, &rect); int left = rect.left + (rect.right - rect.left) / 2; - int top = rect.top + (rect.bottom - rect.top) / 2; + int top = rect.top + (rect.bottom - rect.top) / 2; SetCursorPos(left, top); } -void WindowsRawInputFilter::mousePoll() +void +WindowsRawInputFilter::mousePoll() { - if (mouse_capture || video_fullscreen) - { + if (mouse_capture || video_fullscreen) { static int b = 0; - if (dx != 0 || dy != 0 || dwheel != 0) - { + if (dx != 0 || dy != 0 || dwheel != 0) { mouse_x += dx; mouse_y += dy; mouse_z = dwheel; - dx = 0; - dy = 0; + dx = 0; + dy = 0; dwheel = 0; } - if (b != buttons) - { + if (b != buttons) { mouse_buttons = buttons; - b = buttons; + b = buttons; } } } diff --git a/src/qt/qt_winrawinputfilter.hpp b/src/qt/qt_winrawinputfilter.hpp index dabd3f4dd..252f7206c 100644 --- a/src/qt/qt_winrawinputfilter.hpp +++ b/src/qt/qt_winrawinputfilter.hpp @@ -41,13 +41,12 @@ #include #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) -#define result_t qintptr +# define result_t qintptr #else -#define result_t long +# define result_t long #endif -class WindowsRawInputFilter : public QObject, public QAbstractNativeEventFilter -{ +class WindowsRawInputFilter : public QObject, public QAbstractNativeEventFilter { Q_OBJECT public: @@ -62,20 +61,20 @@ public slots: private: QMainWindow *window; - uint16_t scancode_map[768]; - int buttons = 0; - int dx = 0; - int dy = 0; - int dwheel = 0; - int menus_open = 0; + uint16_t scancode_map[768]; + int buttons = 0; + int dx = 0; + int dy = 0; + int dwheel = 0; + int menus_open = 0; WindowsRawInputFilter(QMainWindow *window); - void handle_input(HRAWINPUT input); - void keyboard_handle(PRAWINPUT raw); - void mouse_handle(PRAWINPUT raw); + void handle_input(HRAWINPUT input); + void keyboard_handle(PRAWINPUT raw); + void mouse_handle(PRAWINPUT raw); static UINT16 convert_scan_code(UINT16 scan_code); - void keyboard_getkeymap(); + void keyboard_getkeymap(); }; #endif diff --git a/src/qt/sdl_joystick.cpp b/src/qt/sdl_joystick.cpp index ab72145c3..06f0a73b8 100644 --- a/src/qt/sdl_joystick.cpp +++ b/src/qt/sdl_joystick.cpp @@ -8,50 +8,47 @@ extern "C" { #include <86box/device.h> #include <86box/gameport.h> -int joysticks_present; -joystick_t joystick_state[MAX_JOYSTICKS]; -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +int joysticks_present; +joystick_t joystick_state[MAX_JOYSTICKS]; +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; } #include #ifndef M_PI -#define M_PI 3.14159265358979323846 +# define M_PI 3.14159265358979323846 #endif -void joystick_init() { +void +joystick_init() +{ if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { return; } joysticks_present = SDL_NumJoysticks(); memset(sdl_joy, 0, sizeof(sdl_joy)); - for (int c = 0; c < joysticks_present; c++) - { + for (int c = 0; c < joysticks_present; c++) { sdl_joy[c] = SDL_JoystickOpen(c); - if (sdl_joy[c]) - { + if (sdl_joy[c]) { int d; strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); - plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); + plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]); - plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); + plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); - for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) - { + for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) { sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d); plat_joystick_state[c].axis[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) - { + for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) { sprintf(plat_joystick_state[c].button[d].name, "Button %i", d); plat_joystick_state[c].button[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) - { + for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) { sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d); plat_joystick_state[c].pov[d].id = d; } @@ -59,59 +56,63 @@ void joystick_init() { } } -void joystick_close() +void +joystick_close() { int c; - for (c = 0; c < joysticks_present; c++) - { + for (c = 0; c < joysticks_present; c++) { if (sdl_joy[c]) SDL_JoystickClose(sdl_joy[c]); } } -static int joystick_get_axis(int joystick_nr, int mapping) +static int +joystick_get_axis(int joystick_nr, int mapping) { - if (mapping & POV_X) - { - switch (plat_joystick_state[joystick_nr].p[mapping & 3]) - { - case SDL_HAT_LEFTUP: case SDL_HAT_LEFT: case SDL_HAT_LEFTDOWN: - return -32767; + if (mapping & POV_X) { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { + case SDL_HAT_LEFTUP: + case SDL_HAT_LEFT: + case SDL_HAT_LEFTDOWN: + return -32767; - case SDL_HAT_RIGHTUP: case SDL_HAT_RIGHT: case SDL_HAT_RIGHTDOWN: - return 32767; + case SDL_HAT_RIGHTUP: + case SDL_HAT_RIGHT: + case SDL_HAT_RIGHTDOWN: + return 32767; - default: - return 0; + default: + return 0; } - } - else if (mapping & POV_Y) - { - switch (plat_joystick_state[joystick_nr].p[mapping & 3]) - { - case SDL_HAT_LEFTUP: case SDL_HAT_UP: case SDL_HAT_RIGHTUP: - return -32767; + } else if (mapping & POV_Y) { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { + case SDL_HAT_LEFTUP: + case SDL_HAT_UP: + case SDL_HAT_RIGHTUP: + return -32767; - case SDL_HAT_LEFTDOWN: case SDL_HAT_DOWN: case SDL_HAT_RIGHTDOWN: - return 32767; + case SDL_HAT_LEFTDOWN: + case SDL_HAT_DOWN: + case SDL_HAT_RIGHTDOWN: + return 32767; - default: - return 0; + default: + return 0; } - } - else + } else return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } -void joystick_process() +void +joystick_process() { int c, d; - if (!joystick_type) return; + if (!joystick_type) + return; SDL_JoystickUpdate(); - for (c = 0; c < joysticks_present; c++) - { + for (c = 0; c < joysticks_present; c++) { int b; plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0); @@ -129,35 +130,30 @@ void joystick_process() // pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); } - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - if (joystick_state[c].plat_joystick_nr) - { + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { + if (joystick_state[c].plat_joystick_nr) { int joystick_nr = joystick_state[c].plat_joystick_nr - 1; for (d = 0; d < joystick_get_axis_count(joystick_type); d++) joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); for (d = 0; d < joystick_get_button_count(joystick_type); d++) joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - int x, y; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { + int x, y; double angle, magnitude; x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); - magnitude = sqrt((double)x*(double)x + (double)y*(double)y); + angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); + magnitude = sqrt((double) x * (double) x + (double) y * (double) y); if (magnitude < 16384) joystick_state[c].pov[d] = -1; else - joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; + joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; } - } - else - { + } else { for (d = 0; d < joystick_get_axis_count(joystick_type); d++) joystick_state[c].axis[d] = 0; for (d = 0; d < joystick_get_button_count(joystick_type); d++) diff --git a/src/qt/win_dynld.c b/src/qt/win_dynld.c index 98eb4739f..66fd0503d 100644 --- a/src/qt/win_dynld.c +++ b/src/qt/win_dynld.c @@ -25,63 +25,59 @@ #include <86box/86box.h> #include <86box/plat_dynld.h> - #ifdef ENABLE_DYNLD_LOG int dynld_do_log = ENABLE_DYNLD_LOG; - static void dynld_log(const char *fmt, ...) { va_list ap; if (dynld_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define dynld_log(fmt, ...) +# define dynld_log(fmt, ...) #endif - void * dynld_module(const char *name, dllimp_t *table) { - HMODULE h; + HMODULE h; dllimp_t *imp; - void *func; + void *func; /* See if we can load the desired module. */ if ((h = LoadLibrary(name)) == NULL) { - dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); - return(NULL); + dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); + return (NULL); } /* Now load the desired function pointers. */ - for (imp=table; imp->name!=NULL; imp++) { - func = GetProcAddress(h, imp->name); - if (func == NULL) { - dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", - name, imp->name, GetLastError()); - FreeLibrary(h); - return(NULL); - } + for (imp = table; imp->name != NULL; imp++) { + func = GetProcAddress(h, imp->name); + if (func == NULL) { + dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", + name, imp->name, GetLastError()); + FreeLibrary(h); + return (NULL); + } - /* To overcome typing issues.. */ - *(char **)imp->func = (char *)func; + /* To overcome typing issues.. */ + *(char **) imp->func = (char *) func; } /* All good. */ dynld_log("loaded %s\n", name); - return((void *)h); + return ((void *) h); } - void dynld_close(void *handle) { if (handle != NULL) - FreeLibrary((HMODULE)handle); + FreeLibrary((HMODULE) handle); } diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index 7aeef6137..f41131b28 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -39,431 +39,444 @@ int joystick_do_log = ENABLE_JOYSTICK_LOG; static void joystick_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (joystick_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } + if (joystick_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } } #else -#define joystick_log(fmt, ...) +# define joystick_log(fmt, ...) #endif typedef struct { - HANDLE hdevice; - PHIDP_PREPARSED_DATA data; + HANDLE hdevice; + PHIDP_PREPARSED_DATA data; - USAGE usage_button[256]; + USAGE usage_button[256]; - struct raw_axis_t { - USAGE usage; - USHORT link; - USHORT bitsize; - LONG max; - LONG min; - } axis[8]; + struct raw_axis_t { + USAGE usage; + USHORT link; + USHORT bitsize; + LONG max; + LONG min; + } axis[8]; - struct raw_pov_t { - USAGE usage; - USHORT link; - LONG max; - LONG min; - } pov[4]; + struct raw_pov_t { + USAGE usage; + USHORT link; + LONG max; + LONG min; + } pov[4]; } raw_joystick_t; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; -int joysticks_present = 0; +joystick_t joystick_state[MAX_JOYSTICKS]; +int joysticks_present = 0; raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; /* We only use the first 32 buttons reported, from Usage ID 1-128 */ -void joystick_add_button(raw_joystick_t* rawjoy, plat_joystick_t* joy, USAGE usage) { - if (joy->nr_buttons >= 32) return; - if (usage < 1 || usage > 128) return; - - rawjoy->usage_button[usage] = joy->nr_buttons; - sprintf(joy->button[joy->nr_buttons].name, "Button %d", usage); - joy->nr_buttons++; -} - -void joystick_add_axis(raw_joystick_t* rawjoy, plat_joystick_t* joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_axes >= 8) return; - - switch (prop->Range.UsageMin) { - case HID_USAGE_GENERIC_X: - sprintf(joy->axis[joy->nr_axes].name, "X"); - break; - case HID_USAGE_GENERIC_Y: - sprintf(joy->axis[joy->nr_axes].name, "Y"); - break; - case HID_USAGE_GENERIC_Z: - sprintf(joy->axis[joy->nr_axes].name, "Z"); - break; - case HID_USAGE_GENERIC_RX: - sprintf(joy->axis[joy->nr_axes].name, "RX"); - break; - case HID_USAGE_GENERIC_RY: - sprintf(joy->axis[joy->nr_axes].name, "RY"); - break; - case HID_USAGE_GENERIC_RZ: - sprintf(joy->axis[joy->nr_axes].name, "RZ"); - break; - default: - return; - } - - joy->axis[joy->nr_axes].id = joy->nr_axes; - rawjoy->axis[joy->nr_axes].usage = prop->Range.UsageMin; - rawjoy->axis[joy->nr_axes].link = prop->LinkCollection; - rawjoy->axis[joy->nr_axes].bitsize = prop->BitSize; - - /* Assume unsigned when min >= 0 */ - if (prop->LogicalMin < 0) { - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax; - } else { - /* - * Some joysticks will send -1 in LogicalMax, like Xbox Controllers - * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) - */ - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1); - } - rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; - - joy->nr_axes++; -} - -void joystick_add_pov(raw_joystick_t* rawjoy, plat_joystick_t* joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_povs >= 4) return; - - sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs+1); - rawjoy->pov[joy->nr_povs].usage = prop->Range.UsageMin; - rawjoy->pov[joy->nr_povs].link = prop->LinkCollection; - rawjoy->pov[joy->nr_povs].min = prop->LogicalMin; - rawjoy->pov[joy->nr_povs].max = prop->LogicalMax; - - joy->nr_povs++; -} - -void joystick_get_capabilities(raw_joystick_t* rawjoy, plat_joystick_t* joy) { - UINT size = 0; - PHIDP_BUTTON_CAPS btn_caps = NULL; - PHIDP_VALUE_CAPS val_caps = NULL; - - /* Get preparsed data (HID data format) */ - GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size); - rawjoy->data = malloc(size); - if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0) - fatal("joystick_get_capabilities: Failed to get preparsed data.\n"); - - HIDP_CAPS caps; - HidP_GetCaps(rawjoy->data, &caps); - - /* Buttons */ - if (caps.NumberInputButtonCaps > 0) { - btn_caps = calloc(caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS)); - if (HidP_GetButtonCaps(HidP_Input, btn_caps, &caps.NumberInputButtonCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { - joystick_log("joystick_get_capabilities: Failed to query input buttons.\n"); - goto end; - } - /* We only detect generic stuff */ - for (int c=0; c 0) { - val_caps = calloc(caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS)); - if (HidP_GetValueCaps(HidP_Input, val_caps, &caps.NumberInputValueCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { - joystick_log("joystick_get_capabilities: Failed to query axes and povs.\n"); - goto end; - } - /* We only detect generic stuff */ - for (int c=0; chdevice, RIDI_DEVICENAME, device_name, &size); - device_name = calloc(size, sizeof(WCHAR)); - if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size) <= 0) - fatal("joystick_get_capabilities: Failed to get device name.\n"); - - HANDLE hDevObj = CreateFileW(device_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (hDevObj) { - HidD_GetProductString(hDevObj, device_desc_wide, sizeof(WCHAR) * 200); - CloseHandle(hDevObj); - } - free(device_name); - - int result = WideCharToMultiByte(CP_ACP, 0, device_desc_wide, 200, joy->name, 260, NULL, NULL); - if (result == 0 || strlen(joy->name) == 0) - sprintf(joy->name, - "RawInput %s, VID:%04lX PID:%04lX", - info->hid.usUsage == HID_USAGE_GENERIC_JOYSTICK ? "Joystick" : "Gamepad", - info->hid.dwVendorId, - info->hid.dwProductId); -} - -void joystick_init() +void +joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) { - UINT size = 0; - atexit(joystick_close); + if (joy->nr_buttons >= 32) + return; + if (usage < 1 || usage > 128) + return; - joysticks_present = 0; - memset(raw_joystick_state, 0, sizeof(raw_joystick_t) * MAX_PLAT_JOYSTICKS); - - /* Get a list of raw input devices from Windows */ - UINT raw_devices = 0; - GetRawInputDeviceList(NULL, &raw_devices, sizeof(RAWINPUTDEVICELIST)); - PRAWINPUTDEVICELIST deviceList = calloc(raw_devices, sizeof(RAWINPUTDEVICELIST)); - GetRawInputDeviceList(deviceList, &raw_devices, sizeof(RAWINPUTDEVICELIST)); - - for (int i=0; i= MAX_PLAT_JOYSTICKS) break; - if (deviceList[i].dwType != RIM_TYPEHID) continue; - - /* Get device info: hardware IDs and usage IDs */ - GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, NULL, &size); - info = malloc(size); - info->cbSize = sizeof(RID_DEVICE_INFO); - if (GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, info, &size) <= 0) - goto end_loop; - - /* If this is not a joystick/gamepad, skip */ - if (info->hid.usUsagePage != HID_USAGE_PAGE_GENERIC) goto end_loop; - if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK && - info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD) goto end_loop; - - plat_joystick_t *joy = &plat_joystick_state[joysticks_present]; - raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present]; - rawjoy->hdevice = deviceList[i].hDevice; - - joystick_get_capabilities(rawjoy, joy); - joystick_get_device_name(rawjoy, joy, info); - - joystick_log("joystick_init: %s - %d buttons, %d axes, %d POVs\n", - joy->name, joy->nr_buttons, joy->nr_axes, joy->nr_povs); - - joysticks_present++; - - end_loop: - free(info); - } - - joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); - - /* Initialize the RawInput (joystick and gamepad) module. */ - RAWINPUTDEVICE ridev[2]; - ridev[0].dwFlags = 0; - ridev[0].hwndTarget = NULL; - ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; - - ridev[1].dwFlags = 0; - ridev[1].hwndTarget = NULL; - ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; - - if (!RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE))) - fatal("plat_joystick_init: RegisterRawInputDevices failed\n"); + rawjoy->usage_button[usage] = joy->nr_buttons; + sprintf(joy->button[joy->nr_buttons].name, "Button %d", usage); + joy->nr_buttons++; } -void joystick_close() +void +joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - RAWINPUTDEVICE ridev[2]; - ridev[0].dwFlags = RIDEV_REMOVE; - ridev[0].hwndTarget = NULL; - ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; + if (joy->nr_axes >= 8) + return; - ridev[1].dwFlags = RIDEV_REMOVE; - ridev[1].hwndTarget = NULL; - ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; + switch (prop->Range.UsageMin) { + case HID_USAGE_GENERIC_X: + sprintf(joy->axis[joy->nr_axes].name, "X"); + break; + case HID_USAGE_GENERIC_Y: + sprintf(joy->axis[joy->nr_axes].name, "Y"); + break; + case HID_USAGE_GENERIC_Z: + sprintf(joy->axis[joy->nr_axes].name, "Z"); + break; + case HID_USAGE_GENERIC_RX: + sprintf(joy->axis[joy->nr_axes].name, "RX"); + break; + case HID_USAGE_GENERIC_RY: + sprintf(joy->axis[joy->nr_axes].name, "RY"); + break; + case HID_USAGE_GENERIC_RZ: + sprintf(joy->axis[joy->nr_axes].name, "RZ"); + break; + default: + return; + } - RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE)); + joy->axis[joy->nr_axes].id = joy->nr_axes; + rawjoy->axis[joy->nr_axes].usage = prop->Range.UsageMin; + rawjoy->axis[joy->nr_axes].link = prop->LinkCollection; + rawjoy->axis[joy->nr_axes].bitsize = prop->BitSize; + + /* Assume unsigned when min >= 0 */ + if (prop->LogicalMin < 0) { + rawjoy->axis[joy->nr_axes].max = prop->LogicalMax; + } else { + /* + * Some joysticks will send -1 in LogicalMax, like Xbox Controllers + * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) + */ + rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1); + } + rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; + + joy->nr_axes++; } - -void win_joystick_handle(PRAWINPUT raw) +void +joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - HRESULT r; - int j = -1; /* current joystick index, -1 when not found */ + if (joy->nr_povs >= 4) + return; - /* If the input is not from a known device, we ignore it */ - for (int i=0; iheader.hDevice) { - j = i; - break; - } - } - if (j == -1) return; + sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); + rawjoy->pov[joy->nr_povs].usage = prop->Range.UsageMin; + rawjoy->pov[joy->nr_povs].link = prop->LinkCollection; + rawjoy->pov[joy->nr_povs].min = prop->LogicalMin; + rawjoy->pov[joy->nr_povs].max = prop->LogicalMax; - /* Read buttons */ - USAGE usage_list[128] = {0}; - ULONG usage_length = plat_joystick_state[j].nr_buttons; - memset(plat_joystick_state[j].b, 0, 32 * sizeof(int)); - - r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length, - raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS) { - for (int i=0; imax - axis->min + 1) / 2; - - r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, - raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS) { - if (axis->min < 0) { - /* extend signed uvalue to LONG */ - if (uvalue & (1 << (axis->bitsize-1))) { - ULONG mask = (1 << axis->bitsize) - 1; - value = -1U ^ mask; - value |= uvalue; - } else { - value = uvalue; - } - } else { - /* Assume unsigned when min >= 0, convert to a signed value */ - value = (LONG)uvalue - center; - } - if (abs(value) == 1) value = 0; - value = value * 32768 / center; - } - - plat_joystick_state[j].a[a] = value; - //joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); - } - - /* read povs */ - for (int p=0; plink, pov->usage, &uvalue, - raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS && (uvalue >= pov->min && uvalue <= pov->max)) { - value = (uvalue - pov->min) * 36000; - value /= (pov->max - pov->min + 1); - value %= 36000; - } - - plat_joystick_state[j].p[p] = value; - - //joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); - - } - //joystick_log("\n"); + joy->nr_povs++; } - -static int joystick_get_axis(int joystick_nr, int mapping) +void +joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_t *joy) { - if (mapping & POV_X) - { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return sin((2*M_PI * (double)pov) / 36000.0) * 32767; - } - else if (mapping & POV_Y) - { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + UINT size = 0; + PHIDP_BUTTON_CAPS btn_caps = NULL; + PHIDP_VALUE_CAPS val_caps = NULL; - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return -cos((2*M_PI * (double)pov) / 36000.0) * 32767; - } - else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; + /* Get preparsed data (HID data format) */ + GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size); + rawjoy->data = malloc(size); + if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0) + fatal("joystick_get_capabilities: Failed to get preparsed data.\n"); + HIDP_CAPS caps; + HidP_GetCaps(rawjoy->data, &caps); + + /* Buttons */ + if (caps.NumberInputButtonCaps > 0) { + btn_caps = calloc(caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS)); + if (HidP_GetButtonCaps(HidP_Input, btn_caps, &caps.NumberInputButtonCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { + joystick_log("joystick_get_capabilities: Failed to query input buttons.\n"); + goto end; + } + /* We only detect generic stuff */ + for (int c = 0; c < caps.NumberInputButtonCaps; c++) { + if (btn_caps[c].UsagePage != HID_USAGE_PAGE_BUTTON) + continue; + + int button_count = btn_caps[c].Range.UsageMax - btn_caps[c].Range.UsageMin + 1; + for (int b = 0; b < button_count; b++) { + joystick_add_button(rawjoy, joy, b + btn_caps[c].Range.UsageMin); + } + } + } + + /* Values (axes and povs) */ + if (caps.NumberInputValueCaps > 0) { + val_caps = calloc(caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS)); + if (HidP_GetValueCaps(HidP_Input, val_caps, &caps.NumberInputValueCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { + joystick_log("joystick_get_capabilities: Failed to query axes and povs.\n"); + goto end; + } + /* We only detect generic stuff */ + for (int c = 0; c < caps.NumberInputValueCaps; c++) { + if (val_caps[c].UsagePage != HID_USAGE_PAGE_GENERIC) + continue; + + if (val_caps[c].Range.UsageMin == HID_USAGE_GENERIC_HATSWITCH) + joystick_add_pov(rawjoy, joy, &val_caps[c]); + else + joystick_add_axis(rawjoy, joy, &val_caps[c]); + } + } + +end: + free(btn_caps); + free(val_caps); } - -void joystick_process(void) +void +joystick_get_device_name(raw_joystick_t *rawjoy, plat_joystick_t *joy, PRID_DEVICE_INFO info) { - int c, d; + UINT size = 0; + WCHAR *device_name = NULL; + WCHAR device_desc_wide[200] = { 0 }; - if (joystick_type == 7) return; + GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size); + device_name = calloc(size, sizeof(WCHAR)); + if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size) <= 0) + fatal("joystick_get_capabilities: Failed to get device name.\n"); - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - if (joystick_state[c].plat_joystick_nr) - { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + HANDLE hDevObj = CreateFileW(device_name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hDevObj) { + HidD_GetProductString(hDevObj, device_desc_wide, sizeof(WCHAR) * 200); + CloseHandle(hDevObj); + } + free(device_name); - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - int x, y; - double angle, magnitude; - - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); - magnitude = sqrt((double)x*(double)x + (double)y*(double)y); - - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; - } - } - else - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } + int result = WideCharToMultiByte(CP_ACP, 0, device_desc_wide, 200, joy->name, 260, NULL, NULL); + if (result == 0 || strlen(joy->name) == 0) + sprintf(joy->name, + "RawInput %s, VID:%04lX PID:%04lX", + info->hid.usUsage == HID_USAGE_GENERIC_JOYSTICK ? "Joystick" : "Gamepad", + info->hid.dwVendorId, + info->hid.dwProductId); +} + +void +joystick_init(void) +{ + UINT size = 0; + atexit(joystick_close); + + joysticks_present = 0; + memset(raw_joystick_state, 0, sizeof(raw_joystick_t) * MAX_PLAT_JOYSTICKS); + + /* Get a list of raw input devices from Windows */ + UINT raw_devices = 0; + GetRawInputDeviceList(NULL, &raw_devices, sizeof(RAWINPUTDEVICELIST)); + PRAWINPUTDEVICELIST deviceList = calloc(raw_devices, sizeof(RAWINPUTDEVICELIST)); + GetRawInputDeviceList(deviceList, &raw_devices, sizeof(RAWINPUTDEVICELIST)); + + for (int i = 0; i < raw_devices; i++) { + PRID_DEVICE_INFO info = NULL; + + if (joysticks_present >= MAX_PLAT_JOYSTICKS) + break; + if (deviceList[i].dwType != RIM_TYPEHID) + continue; + + /* Get device info: hardware IDs and usage IDs */ + GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, NULL, &size); + info = malloc(size); + info->cbSize = sizeof(RID_DEVICE_INFO); + if (GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, info, &size) <= 0) + goto end_loop; + + /* If this is not a joystick/gamepad, skip */ + if (info->hid.usUsagePage != HID_USAGE_PAGE_GENERIC) + goto end_loop; + if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK && info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD) + goto end_loop; + + plat_joystick_t *joy = &plat_joystick_state[joysticks_present]; + raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present]; + rawjoy->hdevice = deviceList[i].hDevice; + + joystick_get_capabilities(rawjoy, joy); + joystick_get_device_name(rawjoy, joy, info); + + joystick_log("joystick_init: %s - %d buttons, %d axes, %d POVs\n", + joy->name, joy->nr_buttons, joy->nr_axes, joy->nr_povs); + + joysticks_present++; + +end_loop: + free(info); + } + + joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); + + /* Initialize the RawInput (joystick and gamepad) module. */ + RAWINPUTDEVICE ridev[2]; + ridev[0].dwFlags = 0; + ridev[0].hwndTarget = NULL; + ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; + + ridev[1].dwFlags = 0; + ridev[1].hwndTarget = NULL; + ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; + + if (!RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE))) + fatal("plat_joystick_init: RegisterRawInputDevices failed\n"); +} + +void +joystick_close(void) +{ + RAWINPUTDEVICE ridev[2]; + ridev[0].dwFlags = RIDEV_REMOVE; + ridev[0].hwndTarget = NULL; + ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; + + ridev[1].dwFlags = RIDEV_REMOVE; + ridev[1].hwndTarget = NULL; + ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; + + RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE)); +} + +void +win_joystick_handle(PRAWINPUT raw) +{ + HRESULT r; + int j = -1; /* current joystick index, -1 when not found */ + + /* If the input is not from a known device, we ignore it */ + for (int i = 0; i < joysticks_present; i++) { + if (raw_joystick_state[i].hdevice == raw->header.hDevice) { + j = i; + break; + } + } + if (j == -1) + return; + + /* Read buttons */ + USAGE usage_list[128] = { 0 }; + ULONG usage_length = plat_joystick_state[j].nr_buttons; + memset(plat_joystick_state[j].b, 0, 32 * sizeof(int)); + + r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length, + raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); + + if (r == HIDP_STATUS_SUCCESS) { + for (int i = 0; i < usage_length; i++) { + int button = raw_joystick_state[j].usage_button[usage_list[i]]; + plat_joystick_state[j].b[button] = 128; + } + } + + /* Read axes */ + for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) { + struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; + ULONG uvalue = 0; + LONG value = 0; + LONG center = (axis->max - axis->min + 1) / 2; + + r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, + raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); + + if (r == HIDP_STATUS_SUCCESS) { + if (axis->min < 0) { + /* extend signed uvalue to LONG */ + if (uvalue & (1 << (axis->bitsize - 1))) { + ULONG mask = (1 << axis->bitsize) - 1; + value = -1U ^ mask; + value |= uvalue; + } else { + value = uvalue; + } + } else { + /* Assume unsigned when min >= 0, convert to a signed value */ + value = (LONG) uvalue - center; + } + if (abs(value) == 1) + value = 0; + value = value * 32768 / center; + } + + plat_joystick_state[j].a[a] = value; + // joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); + } + + /* read povs */ + for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) { + struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; + ULONG uvalue = 0; + LONG value = -1; + + r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue, + raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); + + if (r == HIDP_STATUS_SUCCESS && (uvalue >= pov->min && uvalue <= pov->max)) { + value = (uvalue - pov->min) * 36000; + value /= (pov->max - pov->min + 1); + value %= 36000; + } + + plat_joystick_state[j].p[p] = value; + + // joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); + } + // joystick_log("\n"); +} + +static int +joystick_get_axis(int joystick_nr, int mapping) +{ + if (mapping & POV_X) { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return sin((2 * M_PI * (double) pov) / 36000.0) * 32767; + } else if (mapping & POV_Y) { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; + } else + return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; +} + +void +joystick_process(void) +{ + int c, d; + + if (joystick_type == 7) + return; + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { + if (joystick_state[c].plat_joystick_nr) { + int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; + + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { + int x, y; + double angle, magnitude; + + x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); + y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); + + angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); + magnitude = sqrt((double) x * (double) x + (double) y * (double) y); + + if (magnitude < 16384) + joystick_state[c].pov[d] = -1; + else + joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; + } + } else { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = 0; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = 0; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + joystick_state[c].pov[d] = -1; + } + } } diff --git a/src/qt/wl_mouse.cpp b/src/qt/wl_mouse.cpp index 9e487cde3..4cc1b3169 100644 --- a/src/qt/wl_mouse.cpp +++ b/src/qt/wl_mouse.cpp @@ -25,40 +25,39 @@ #include #include -extern "C" -{ +extern "C" { #include <86box/plat.h> } -static zwp_relative_pointer_manager_v1* rel_manager = nullptr; -static zwp_relative_pointer_v1* rel_pointer = nullptr; -static zwp_pointer_constraints_v1* conf_pointer_interface = nullptr; -static zwp_locked_pointer_v1* conf_pointer = nullptr; +static zwp_relative_pointer_manager_v1 *rel_manager = nullptr; +static zwp_relative_pointer_v1 *rel_pointer = nullptr; +static zwp_pointer_constraints_v1 *conf_pointer_interface = nullptr; +static zwp_locked_pointer_v1 *conf_pointer = nullptr; -static int rel_mouse_x = 0, rel_mouse_y = 0; +static int rel_mouse_x = 0, rel_mouse_y = 0; static bool wl_init_ok = false; -void rel_mouse_event(void* data, zwp_relative_pointer_v1* zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real) +void +rel_mouse_event(void *data, zwp_relative_pointer_v1 *zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real) { rel_mouse_x += wl_fixed_to_int(dx_real); rel_mouse_y += wl_fixed_to_int(dy_real); } -extern "C" -{ - extern int mouse_x, mouse_y; +extern "C" { +extern int mouse_x, mouse_y; } -void wl_mouse_poll() +void +wl_mouse_poll() { - mouse_x = rel_mouse_x; - mouse_y = rel_mouse_y; + mouse_x = rel_mouse_x; + mouse_y = rel_mouse_y; rel_mouse_x = 0; rel_mouse_y = 0; } -static struct zwp_relative_pointer_v1_listener rel_listener = -{ +static struct zwp_relative_pointer_v1_listener rel_listener = { rel_mouse_event }; @@ -66,13 +65,11 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) { - if (!strcmp(interface, "zwp_relative_pointer_manager_v1")) - { - rel_manager = (zwp_relative_pointer_manager_v1*)wl_registry_bind(registry, id, &zwp_relative_pointer_manager_v1_interface, version); + if (!strcmp(interface, "zwp_relative_pointer_manager_v1")) { + rel_manager = (zwp_relative_pointer_manager_v1 *) wl_registry_bind(registry, id, &zwp_relative_pointer_manager_v1_interface, version); } - if (!strcmp(interface, "zwp_pointer_constraints_v1")) - { - conf_pointer_interface = (zwp_pointer_constraints_v1*)wl_registry_bind(registry, id, &zwp_pointer_constraints_v1_interface, version); + if (!strcmp(interface, "zwp_pointer_constraints_v1")) { + conf_pointer_interface = (zwp_pointer_constraints_v1 *) wl_registry_bind(registry, id, &zwp_pointer_constraints_v1_interface, version); } } @@ -82,7 +79,7 @@ display_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name plat_mouse_capture(0); zwp_relative_pointer_manager_v1_destroy(rel_manager); zwp_pointer_constraints_v1_destroy(conf_pointer_interface); - rel_manager = nullptr; + rel_manager = nullptr; conf_pointer_interface = nullptr; } @@ -91,15 +88,14 @@ static const struct wl_registry_listener registry_listener = { display_global_remove }; -void wl_init() +void +wl_init() { if (!wl_init_ok) { - wl_display* display = (wl_display*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display"); - if (display) - { + wl_display *display = (wl_display *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display"); + if (display) { auto registry = wl_display_get_registry(display); - if (registry) - { + if (registry) { wl_registry_add_listener(registry, ®istry_listener, nullptr); wl_display_roundtrip(display); } @@ -108,19 +104,24 @@ void wl_init() } } -void wl_mouse_capture(QWindow *window) +void +wl_mouse_capture(QWindow *window) { if (rel_manager) { - rel_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(rel_manager, (wl_pointer*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer")); + rel_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(rel_manager, (wl_pointer *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer")); zwp_relative_pointer_v1_add_listener(rel_pointer, &rel_listener, nullptr); } - if (conf_pointer_interface) conf_pointer = zwp_pointer_constraints_v1_lock_pointer(conf_pointer_interface, (wl_surface*)QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_pointer*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer"), nullptr, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); + if (conf_pointer_interface) + conf_pointer = zwp_pointer_constraints_v1_lock_pointer(conf_pointer_interface, (wl_surface *) QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_pointer *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer"), nullptr, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); } -void wl_mouse_uncapture() +void +wl_mouse_uncapture() { - if (conf_pointer) zwp_locked_pointer_v1_destroy(conf_pointer); - if (rel_pointer) zwp_relative_pointer_v1_destroy(rel_pointer); - rel_pointer = nullptr; + if (conf_pointer) + zwp_locked_pointer_v1_destroy(conf_pointer); + if (rel_pointer) + zwp_relative_pointer_v1_destroy(rel_pointer); + rel_pointer = nullptr; conf_pointer = nullptr; } diff --git a/src/qt/wl_mouse.hpp b/src/qt/wl_mouse.hpp index a62d70fee..25d4de66c 100644 --- a/src/qt/wl_mouse.hpp +++ b/src/qt/wl_mouse.hpp @@ -1,5 +1,5 @@ class QWindow; -void wl_mouse_capture(QWindow* window); +void wl_mouse_capture(QWindow *window); void wl_mouse_uncapture(); void wl_mouse_poll(); void wl_init(); diff --git a/src/qt/xinput2_mouse.cpp b/src/qt/xinput2_mouse.cpp index b1887bedc..5017c78d2 100644 --- a/src/qt/xinput2_mouse.cpp +++ b/src/qt/xinput2_mouse.cpp @@ -23,7 +23,7 @@ #include #include "qt_mainwindow.hpp" -extern MainWindow* main_window; +extern MainWindow *main_window; #include #include @@ -31,8 +31,7 @@ extern MainWindow* main_window; #include -extern "C" -{ +extern "C" { #include #include #include @@ -46,27 +45,29 @@ extern "C" int xi2flides[2] = { 0, 0 }; -static Display* disp = nullptr; -static QThread* procThread = nullptr; -static XIEventMask ximask; -static std::atomic exitfromthread = false; +static Display *disp = nullptr; +static QThread *procThread = nullptr; +static XIEventMask ximask; +static std::atomic exitfromthread = false; static std::atomic xi2_mouse_x = 0, xi2_mouse_y = 0, xi2_mouse_abs_x = 0, xi2_mouse_abs_y = 0; -static int xi2opcode = 0; -static double prev_rel_coords[2] = { 0., 0. }; -static Time prev_time = 0; +static int xi2opcode = 0; +static double prev_rel_coords[2] = { 0., 0. }; +static Time prev_time = 0; // From SDL2. -static void parse_valuators(const double *input_values, const unsigned char *mask,int mask_len, - double *output_values,int output_values_len) { - int i = 0,z = 0; +static void +parse_valuators(const double *input_values, const unsigned char *mask, int mask_len, + double *output_values, int output_values_len) +{ + int i = 0, z = 0; int top = mask_len * 8; if (top > 16) top = 16; - memset(output_values,0,output_values_len * sizeof(double)); + memset(output_values, 0, output_values_len * sizeof(double)); for (; i < top && z < output_values_len; i++) { if (XIMaskIsSet(mask, i)) { - const int value = (int) *input_values; + const int value = (int) *input_values; output_values[z] = value; input_values++; } @@ -76,100 +77,102 @@ static void parse_valuators(const double *input_values, const unsigned char *mas static bool exitthread = false; -void xinput2_proc() +void +xinput2_proc() { Window win; win = DefaultRootWindow(disp); ximask.deviceid = XIAllMasterDevices; ximask.mask_len = XIMaskLen(XI_LASTEVENT); - ximask.mask = (unsigned char*)calloc(ximask.mask_len, sizeof(unsigned char)); + ximask.mask = (unsigned char *) calloc(ximask.mask_len, sizeof(unsigned char)); XISetMask(ximask.mask, XI_RawKeyPress); XISetMask(ximask.mask, XI_RawKeyRelease); XISetMask(ximask.mask, XI_RawButtonPress); XISetMask(ximask.mask, XI_RawButtonRelease); XISetMask(ximask.mask, XI_RawMotion); - if (XKeysymToKeycode(disp, XK_Home) == 69) XISetMask(ximask.mask, XI_Motion); + if (XKeysymToKeycode(disp, XK_Home) == 69) + XISetMask(ximask.mask, XI_Motion); XISelectEvents(disp, win, &ximask, 1); XSync(disp, False); - while(true) - { - XEvent ev; - XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie; - XNextEvent(disp, (XEvent*)&ev); + while (true) { + XEvent ev; + XGenericEventCookie *cookie = (XGenericEventCookie *) &ev.xcookie; + XNextEvent(disp, (XEvent *) &ev); if (XGetEventData(disp, cookie) && cookie->type == GenericEvent && cookie->extension == xi2opcode) { switch (cookie->evtype) { - case XI_RawMotion: { - const XIRawEvent *rawev = (const XIRawEvent*)cookie->data; - double relative_coords[2] = { 0., 0. }; - parse_valuators(rawev->raw_values,rawev->valuators.mask, - rawev->valuators.mask_len,relative_coords,2); + case XI_RawMotion: + { + const XIRawEvent *rawev = (const XIRawEvent *) cookie->data; + double relative_coords[2] = { 0., 0. }; + parse_valuators(rawev->raw_values, rawev->valuators.mask, + rawev->valuators.mask_len, relative_coords, 2); - if ((rawev->time == prev_time) && (relative_coords[0] == prev_rel_coords[0]) && (relative_coords[1] == prev_rel_coords[1])) { - break; // Ignore duplicated events. - } - xi2_mouse_x = xi2_mouse_x + relative_coords[0]; - xi2_mouse_y = xi2_mouse_y + relative_coords[1]; - prev_rel_coords[0] = relative_coords[0]; - prev_rel_coords[1] = relative_coords[1]; - prev_time = rawev->time; - if (!mouse_capture) break; - XWindowAttributes winattrib{}; - if (XGetWindowAttributes(disp, main_window->winId(), &winattrib)) { - auto globalPoint = main_window->mapToGlobal(QPoint(main_window->width() / 2, main_window->height() / 2)); - XWarpPointer(disp, XRootWindow(disp, XScreenNumberOfScreen(winattrib.screen)), XRootWindow(disp, XScreenNumberOfScreen(winattrib.screen)), 0, 0, 0, 0, globalPoint.x(), globalPoint.y()); - XFlush(disp); - } - - } - case XI_Motion: { - if (XKeysymToKeycode(disp, XK_Home) == 69) { - // No chance we will get raw motion events on VNC. - const XIDeviceEvent *motionev = (const XIDeviceEvent*)cookie->data; - if (xi2_mouse_abs_x != 0 || xi2_mouse_abs_y != 0) { - xi2_mouse_x = xi2_mouse_x + (motionev->event_x - xi2_mouse_abs_x); - xi2_mouse_y = xi2_mouse_y + (motionev->event_y - xi2_mouse_abs_y); + if ((rawev->time == prev_time) && (relative_coords[0] == prev_rel_coords[0]) && (relative_coords[1] == prev_rel_coords[1])) { + break; // Ignore duplicated events. + } + xi2_mouse_x = xi2_mouse_x + relative_coords[0]; + xi2_mouse_y = xi2_mouse_y + relative_coords[1]; + prev_rel_coords[0] = relative_coords[0]; + prev_rel_coords[1] = relative_coords[1]; + prev_time = rawev->time; + if (!mouse_capture) + break; + XWindowAttributes winattrib {}; + if (XGetWindowAttributes(disp, main_window->winId(), &winattrib)) { + auto globalPoint = main_window->mapToGlobal(QPoint(main_window->width() / 2, main_window->height() / 2)); + XWarpPointer(disp, XRootWindow(disp, XScreenNumberOfScreen(winattrib.screen)), XRootWindow(disp, XScreenNumberOfScreen(winattrib.screen)), 0, 0, 0, 0, globalPoint.x(), globalPoint.y()); + XFlush(disp); + } + } + case XI_Motion: + { + if (XKeysymToKeycode(disp, XK_Home) == 69) { + // No chance we will get raw motion events on VNC. + const XIDeviceEvent *motionev = (const XIDeviceEvent *) cookie->data; + if (xi2_mouse_abs_x != 0 || xi2_mouse_abs_y != 0) { + xi2_mouse_x = xi2_mouse_x + (motionev->event_x - xi2_mouse_abs_x); + xi2_mouse_y = xi2_mouse_y + (motionev->event_y - xi2_mouse_abs_y); + } + xi2_mouse_abs_x = motionev->event_x; + xi2_mouse_abs_y = motionev->event_y; } - xi2_mouse_abs_x = motionev->event_x; - xi2_mouse_abs_y = motionev->event_y; } - } } } XFreeEventData(disp, cookie); - if (exitthread) break; + if (exitthread) + break; } XCloseDisplay(disp); } -void xinput2_exit() +void +xinput2_exit() { - if (!exitthread) - { + if (!exitthread) { exitthread = true; procThread->wait(5000); procThread->terminate(); } } -void xinput2_init() +void +xinput2_init() { disp = XOpenDisplay(nullptr); - if (!disp) - { + if (!disp) { qWarning() << "Cannot open current X11 display"; return; } auto event = 0, err = 0, minor = 1, major = 2; - if (XQueryExtension(disp, "XInputExtension", &xi2opcode, &event, &err)) - { - if (XIQueryVersion(disp, &major, &minor) == Success) - { + if (XQueryExtension(disp, "XInputExtension", &xi2opcode, &event, &err)) { + if (XIQueryVersion(disp, &major, &minor) == Success) { procThread = QThread::create(xinput2_proc); procThread->start(); atexit(xinput2_exit); @@ -177,10 +180,10 @@ void xinput2_init() } } -void xinput2_poll() +void +xinput2_poll() { - if (procThread && mouse_capture) - { + if (procThread && mouse_capture) { mouse_x = xi2_mouse_x; mouse_y = xi2_mouse_y; } diff --git a/src/random.c b/src/random.c index 9deea1f56..18c52ef02 100644 --- a/src/random.c +++ b/src/random.c @@ -1,18 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * A better random number generation, used for floppy weak bits - * and network MAC address generation. + * A better random number generation, used for floppy weak bits + * and network MAC address generation. * * * - * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. + * Authors: Miran Grca, + * + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -53,9 +54,9 @@ rdtsc(void) unsigned hi, lo; # ifdef _MSC_VER __asm { - rdtsc - mov hi, edx ; EDX:EAX is already standard return!! - mov lo, eax + rdtsc + mov hi, edx ; EDX:EAX is already standard return!! + mov lo, eax } # else __asm__ __volatile__("rdtsc" diff --git a/src/scsi/CMakeLists.txt b/src/scsi/CMakeLists.txt index 4518e0aa8..467affd5a 100644 --- a/src/scsi/CMakeLists.txt +++ b/src/scsi/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(scsi OBJECT scsi.c scsi_device.c scsi_cdrom.c scsi_disk.c diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 5cd4b7287..5f9abe8d6 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handling of the SCSI controllers. + * Handling of the SCSI controllers. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, - * TheCollector1995, + * Authors: Miran Grca, + * Fred N. van Kempen, + * TheCollector1995, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017-2018 Fred N. van Kempen. */ #include #include @@ -179,8 +179,8 @@ scsi_card_init(void) if (machine_has_flags(machine, MACHINE_SCSI)) max--; -/* Do not initialize any controllers if we have do not have any SCSI - bus left. */ + /* Do not initialize any controllers if we have do not have any SCSI + bus left. */ if (max > 0) { for (i = 0; i < max; i++) { if (!scsi_cards[scsi_card_current[i]].device) diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index b94759782..669d050bf 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the AHA-154x series of SCSI Host Adapters - * made by Adaptec, Inc. These controllers were designed for - * the ISA bus. + * Implementation of the AHA-154x series of SCSI Host Adapters + * made by Adaptec, Inc. These controllers were designed for + * the ISA bus. * * * - * Authors: Fred N. van Kempen, - * Original Buslogic version by SA1988 and Miran Grca. + * Authors: Fred N. van Kempen, + * Original Buslogic version by SA1988 and Miran Grca. * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2018 Fred N. van Kempen. */ #include #include @@ -519,7 +519,7 @@ aha_mca_write(int port, uint8_t val, void *priv) /* Get the new assigned I/O base address. */ dev->Base = (dev->pos_regs[3] & 7) << 8; - dev->Base |= ((dev->pos_regs[3] & 0xc0) ? 0x34 : 0x30); + dev->Base |= ((dev->pos_regs[3] & 0x40) ? 0x34 : 0x30); /* Save the new IRQ and DMA channel values. */ dev->Irq = (dev->pos_regs[4] & 0x07) + 8; diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 38d7922ba..c0b0575df 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1,24 +1,24 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of BusLogic ISA and PCI SCSI controllers. Boards - * supported: + * Emulation of BusLogic ISA and PCI SCSI controllers. Boards + * supported: * - * 0 - BT-542BH ISA; - * 1 - BT-545S ISA; - * 2 - BT-958D PCI + * 0 - BT-542BH ISA; + * 1 - BT-545S ISA; + * 2 - BT-958D PCI * * * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, + * Authors: TheCollector1995, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017-2018 Fred N. van Kempen. */ #include #include diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index bee60bb5f..80ff4184a 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the CD-ROM drive with SCSI(-like) - * commands, for both ATAPI and SCSI usage. + * Implementation of the CD-ROM drive with SCSI(-like) + * commands, for both ATAPI and SCSI usage. * * * - * Author: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -30,6 +30,7 @@ #include <86box/device.h> #include <86box/scsi.h> #include <86box/scsi_device.h> +#include <86box/machine.h> #include <86box/nvr.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -62,98 +63,98 @@ typedef struct /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ const uint8_t scsi_cdrom_command_flags[0x100] = { - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, /* 0x02 */ - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - 0, 0, 0, 0, /* 0x04-0x07 */ - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, 0, /* 0x09-0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - 0, 0, 0, 0, 0, 0, /* 0x0C-0x11 */ - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, /* 0x14 */ - IMPLEMENTED, /* 0x15 */ - 0, 0, 0, 0, /* 0x16-0x19 */ - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, 0, /* 0x1C-0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, /* 0x1F-0x24 */ - IMPLEMENTED | CHECK_READY, /* 0x25 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY | EARLY_ONLY,/* 0x26 */ - 0, /* 0x27 */ - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, 0, /* 0x29-0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, 0, /* 0x2C-0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F */ - 0, 0, /* 0x40-0x41 */ - IMPLEMENTED | CHECK_READY, /* 0x42 */ - IMPLEMENTED | CHECK_READY, /* 0x43 - Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS - NOTE: The ATAPI reference says otherwise, but I think this is a question of - interpreting things right - the UNIT ATTENTION condition we have here - is a tradition from not ready to ready, by definition the drive - eventually becomes ready, make the condition go away. */ - IMPLEMENTED | CHECK_READY, /* 0x44 */ - IMPLEMENTED | CHECK_READY, /* 0x45 */ - IMPLEMENTED | ALLOW_UA, /* 0x46 */ - IMPLEMENTED | CHECK_READY, /* 0x47 */ - IMPLEMENTED | CHECK_READY, /* 0x48 */ - IMPLEMENTED | CHECK_READY, /* 0x49 */ - IMPLEMENTED | ALLOW_UA, /* 0x4A */ - IMPLEMENTED | CHECK_READY, /* 0x4B */ - 0, 0, /* 0x4C-0x4D */ - IMPLEMENTED | CHECK_READY, /* 0x4E */ - 0, 0, /* 0x4F-0x50 */ - IMPLEMENTED | CHECK_READY, /* 0x51 */ - IMPLEMENTED | CHECK_READY, /* 0x52 */ - 0, 0, /* 0x53-0x54 */ - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, /* 0x56-0x59 */ - IMPLEMENTED, /* 0x5A */ - 0, 0, 0, 0, 0, /* 0x5B-0x5F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */ - 0, 0, 0, 0, 0, /* 0xA0-0xA4 */ - IMPLEMENTED | CHECK_READY, /* 0xA5 */ - 0, 0, /* 0xA6-0xA7 */ - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - IMPLEMENTED | CHECK_READY, /* 0xA9 */ - 0, 0, 0, /* 0xAA-0xAC */ - IMPLEMENTED | CHECK_READY, /* 0xAD */ - 0, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, /* 0xB0-0xB3 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB4 */ - 0, 0, 0, /* 0xB5-0xB7 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB8 */ - IMPLEMENTED | CHECK_READY, /* 0xB9 */ - IMPLEMENTED | CHECK_READY, /* 0xBA */ - IMPLEMENTED, /* 0xBB */ - IMPLEMENTED | CHECK_READY, /* 0xBC */ - IMPLEMENTED, /* 0xBD */ - IMPLEMENTED | CHECK_READY, /* 0xBE */ - IMPLEMENTED | CHECK_READY, /* 0xBF */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC0 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC1 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ - 0, /* 0xC3 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC4 */ - 0, /* 0xC5 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC6 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC7 */ - 0, 0, 0, 0, 0, /* 0xC8-0xCC */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD9 */ - IMPLEMENTED | SCSI_ONLY, /* 0xDA */ - 0, 0, 0, 0, 0, /* 0xDB-0xDF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ + IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ + 0, /* 0x02 */ + IMPLEMENTED | ALLOW_UA, /* 0x03 */ + 0, 0, 0, 0, /* 0x04-0x07 */ + IMPLEMENTED | CHECK_READY, /* 0x08 */ + 0, 0, /* 0x09-0x0A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ + 0, 0, 0, 0, 0, 0, /* 0x0C-0x11 */ + IMPLEMENTED | ALLOW_UA, /* 0x12 */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ + 0, /* 0x14 */ + IMPLEMENTED, /* 0x15 */ + 0, 0, 0, 0, /* 0x16-0x19 */ + IMPLEMENTED, /* 0x1A */ + IMPLEMENTED | CHECK_READY, /* 0x1B */ + 0, 0, /* 0x1C-0x1D */ + IMPLEMENTED | CHECK_READY, /* 0x1E */ + 0, 0, 0, 0, 0, 0, /* 0x1F-0x24 */ + IMPLEMENTED | CHECK_READY, /* 0x25 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY | EARLY_ONLY, /* 0x26 */ + 0, /* 0x27 */ + IMPLEMENTED | CHECK_READY, /* 0x28 */ + 0, 0, /* 0x29-0x2A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ + 0, 0, 0, /* 0x2C-0x2E */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F */ + 0, 0, /* 0x40-0x41 */ + IMPLEMENTED | CHECK_READY, /* 0x42 */ + IMPLEMENTED | CHECK_READY, /* 0x43 - Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS + NOTE: The ATAPI reference says otherwise, but I think this is a question of + interpreting things right - the UNIT ATTENTION condition we have here + is a tradition from not ready to ready, by definition the drive + eventually becomes ready, make the condition go away. */ + IMPLEMENTED | CHECK_READY, /* 0x44 */ + IMPLEMENTED | CHECK_READY, /* 0x45 */ + IMPLEMENTED | ALLOW_UA, /* 0x46 */ + IMPLEMENTED | CHECK_READY, /* 0x47 */ + IMPLEMENTED | CHECK_READY, /* 0x48 */ + IMPLEMENTED | CHECK_READY, /* 0x49 */ + IMPLEMENTED | ALLOW_UA, /* 0x4A */ + IMPLEMENTED | CHECK_READY, /* 0x4B */ + 0, 0, /* 0x4C-0x4D */ + IMPLEMENTED | CHECK_READY, /* 0x4E */ + 0, 0, /* 0x4F-0x50 */ + IMPLEMENTED | CHECK_READY, /* 0x51 */ + IMPLEMENTED | CHECK_READY, /* 0x52 */ + 0, 0, /* 0x53-0x54 */ + IMPLEMENTED, /* 0x55 */ + 0, 0, 0, 0, /* 0x56-0x59 */ + IMPLEMENTED, /* 0x5A */ + 0, 0, 0, 0, 0, /* 0x5B-0x5F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */ + 0, 0, 0, 0, 0, /* 0xA0-0xA4 */ + IMPLEMENTED | CHECK_READY, /* 0xA5 */ + 0, 0, /* 0xA6-0xA7 */ + IMPLEMENTED | CHECK_READY, /* 0xA8 */ + IMPLEMENTED | CHECK_READY, /* 0xA9 */ + 0, 0, 0, /* 0xAA-0xAC */ + IMPLEMENTED | CHECK_READY, /* 0xAD */ + 0, /* 0xAE */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ + 0, 0, 0, 0, /* 0xB0-0xB3 */ + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB4 */ + 0, 0, 0, /* 0xB5-0xB7 */ + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB8 */ + IMPLEMENTED | CHECK_READY, /* 0xB9 */ + IMPLEMENTED | CHECK_READY, /* 0xBA */ + IMPLEMENTED, /* 0xBB */ + IMPLEMENTED | CHECK_READY, /* 0xBC */ + IMPLEMENTED, /* 0xBD */ + IMPLEMENTED | CHECK_READY, /* 0xBE */ + IMPLEMENTED | CHECK_READY, /* 0xBF */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC0 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC1 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ + 0, /* 0xC3 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC4 */ + 0, /* 0xC5 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC6 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC7 */ + 0, 0, 0, 0, 0, /* 0xC8-0xCC */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD9 */ + IMPLEMENTED | SCSI_ONLY, /* 0xDA */ + 0, 0, 0, 0, 0, /* 0xDB-0xDF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ }; static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); @@ -349,12 +350,12 @@ scsi_cdrom_init(scsi_cdrom_t *dev) dev->drv->bus_mode |= 1; scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); - dev->sense[0] = 0xf0; - dev->sense[7] = 10; + dev->sense[0] = 0xf0; + dev->sense[7] = 10; if (dev->early) - dev->status = READY_STAT | DSC_STAT; + dev->status = READY_STAT | DSC_STAT; else - dev->status = 0; + dev->status = 0; dev->pos = 0; dev->packet_status = PHASE_NONE; scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; @@ -518,18 +519,29 @@ scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t pag buf[pos++] = msplen; scsi_cdrom_log("CD-ROM %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); for (j = 0; j < msplen; j++) { - if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { - if (j & 1) - buf[pos++] = ((dev->drv->speed * 176) & 0xff); - else - buf[pos++] = ((dev->drv->speed * 176) >> 8); - } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 12) && (j <= 13)) { - if (j & 1) - buf[pos++] = ((dev->drv->cur_speed * 176) & 0xff); - else - buf[pos++] = ((dev->drv->cur_speed * 176) >> 8); - } else + /* If we are returning changeable values, always return them from the page, + so they are all correctly. */ + if (page_control == 1) buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j); + else { + if ((i == GPMODE_CAPABILITIES_PAGE) && (j == 4)) { + buf[pos] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j) & 0x1f; + /* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and Toshiba CDS-431) are + caddy drives, the later ones are tray drives. */ + buf[pos++] |= (dev->early ? 0x00 : 0x20); + } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { + if (j & 1) + buf[pos++] = ((dev->drv->speed * 176) & 0xff); + else + buf[pos++] = ((dev->drv->speed * 176) >> 8); + } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 12) && (j <= 13)) { + if (j & 1) + buf[pos++] = ((dev->drv->cur_speed * 176) & 0xff); + else + buf[pos++] = ((dev->drv->cur_speed * 176) >> 8); + } else + buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j); + } } } } @@ -542,7 +554,7 @@ static void scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) { int32_t bt, min_len = 0; - double dlen; + double dlen; dev->max_transfer_len = dev->request_length; @@ -559,11 +571,11 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) that a media access comand does not DRQ in the middle of a sector. One of the drivers that relies on the correctness of this behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS which uses the READ CD command to read data on some CD types. */ - if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { - /* Round to sector length. */ - dlen = ((double) dev->max_transfer_len) / ((double) block_len); - dev->max_transfer_len = ((uint16_t) floor(dlen)) * block_len; - } + if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { + /* Round to sector length. */ + dlen = ((double) dev->max_transfer_len) / ((double) block_len); + dev->max_transfer_len = ((uint16_t) floor(dlen)) * block_len; + } } else { /* Round it to the nearest 2048 bytes. */ dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; @@ -1381,14 +1393,14 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) int ret, format = 0; int real_pos, track = 0; #ifdef USE_86BOX_CD - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; - char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; + char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; #endif - int32_t blen = 0, *BufLen; - uint8_t *b; - uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + int32_t blen = 0, *BufLen; + uint8_t *b; + uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; + uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type == CDROM_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; @@ -2024,7 +2036,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) if (dev->early) { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); scsi_cdrom_stop(sc); - cdrom_eject(dev->id); + cdrom_eject(dev->id); scsi_cdrom_command_complete(dev); } else { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); @@ -2362,13 +2374,15 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) } else { if (dev->early) ide_padstr8(dev->buffer + idx, 8, "NEC"); /* Vendor */ + else if (machine_is_sony()) + ide_padstr8(dev->buffer + idx, 8, "SONY"); /* Vendor */ else ide_padstr8(dev->buffer + idx, 8, "HITACHI"); /* Vendor */ } #endif idx += 8; #ifdef USE_86BOX_CD - ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ + ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ #else if (dev->drv->bus_type == CDROM_BUS_SCSI) { if (dev->early) @@ -2378,6 +2392,8 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) } else { if (dev->early) ide_padstr8(dev->buffer + idx, 40, "CD-ROM DRIVE:260"); /* Product */ + else if (machine_is_sony()) + ide_padstr8(dev->buffer + idx, 40, "CD-ROM CDU76"); /* Product */ else ide_padstr8(dev->buffer + idx, 40, "CDR-8130"); /* Product */ } @@ -2435,6 +2451,10 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) ide_padstr8(dev->buffer + 8, 8, "NEC"); /* Vendor */ ide_padstr8(dev->buffer + 16, 16, "CD-ROM DRIVE:260"); /* Product */ ide_padstr8(dev->buffer + 32, 4, "1.01"); /* Revision */ + } else if (machine_is_sony()) { + ide_padstr8(dev->buffer + 8, 8, "SONY"); /* Vendor */ + ide_padstr8(dev->buffer + 16, 16, "CD-ROM CDU76"); /* Product */ + ide_padstr8(dev->buffer + 32, 4, "1.0i"); /* Revision */ } else { ide_padstr8(dev->buffer + 8, 8, "HITACHI"); /* Vendor */ ide_padstr8(dev->buffer + 16, 16, "CDR-8130"); /* Product */ @@ -2711,7 +2731,7 @@ scsi_cdrom_identify(ide_t *ide, int ide_has_dma) { #ifdef USE_86BOX_CD scsi_cdrom_t *dev; - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; dev = (scsi_cdrom_t *) ide->sc; @@ -2725,19 +2745,22 @@ scsi_cdrom_identify(ide_t *ide, int ide_has_dma) ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (1 << 5); /* ATAPI device, CD-ROM drive, removable media, interrupt DRQ */ else ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (2 << 5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ #ifdef USE_86BOX_CD - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ #else if (dev->early) { -#ifdef WRONG +# ifdef WRONG ide_padstr((char *) (ide->buffer + 23), "1.01 ", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:260 ", 40); /* Model */ -#else +# else ide_padstr((char *) (ide->buffer + 23), ".110 ", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "EN C DCR-MOD IREV2:06 ", 40); /* Model */ -#endif +# endif + } else if (machine_is_sony()) { + ide_padstr((char *) (ide->buffer + 23), "1.0i ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "CD-ROM CDU76 ", 40); /* Model */ } else { ide_padstr((char *) (ide->buffer + 23), "0020 ", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "HITACHI CDR-8130 ", 40); /* Model */ @@ -2789,7 +2812,7 @@ scsi_cdrom_drive_reset(int c) dev->drv = drv; dev->cur_lun = SCSI_LUN_USE_CDB; - dev->early = dev->drv->early; + dev->early = dev->drv->early; drv->insert = scsi_cdrom_insert; drv->get_volume = scsi_cdrom_get_volume; diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index ad87c7460..721411bd8 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * The generic SCSI device command handler. + * The generic SCSI device command handler. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017-2018 Fred N. van Kempen. */ #include #include diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index ccf35a2c8..5cc48b906 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -1,16 +1,16 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * Emulation of SCSI fixed disks. + * Emulation of SCSI fixed disks. * * * - * Author: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2017,2018 Miran Grca. + * Copyright 2017-2018 Miran Grca. */ #include #include diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index b022d59dd..668f9ea9f 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the NCR 5380 series of SCSI Host Adapters - * made by NCR. These controllers were designed for the ISA bus. + * Implementation of the NCR 5380 series of SCSI Host Adapters + * made by NCR. These controllers were designed for the ISA bus. * * * - * Authors: Sarah Walker, - * TheCollector1995, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * TheCollector1995, + * Fred N. van Kempen, * - * Copyright 2017-2019 Sarah Walker. - * Copyright 2017-2019 TheCollector1995. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2019 Sarah Walker. + * Copyright 2017-2019 TheCollector1995. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include @@ -1354,22 +1354,7 @@ t128_read(uint32_t addr, void *priv) ret = ncr_dev->t128.status; ncr_log("T128 status read = %02x, cur bus = %02x, req = %02x, dma = %02x\n", ret, ncr->cur_bus, ncr->cur_bus & BUS_REQ, ncr->mode & MODE_DMA); } else if (addr >= 0x1d00 && addr < 0x1e00) { - if (addr >= 0x1d00 && addr < 0x1d20) - ret = ncr_read(0, ncr_dev); - else if (addr >= 0x1d20 && addr < 0x1d40) - ret = ncr_read(1, ncr_dev); - else if (addr >= 0x1d40 && addr < 0x1d60) - ret = ncr_read(2, ncr_dev); - else if (addr >= 0x1d60 && addr < 0x1d80) - ret = ncr_read(3, ncr_dev); - else if (addr >= 0x1d80 && addr < 0x1da0) - ret = ncr_read(4, ncr_dev); - else if (addr >= 0x1da0 && addr < 0x1dc0) - ret = ncr_read(5, ncr_dev); - else if (addr >= 0x1dc0 && addr < 0x1de0) - ret = ncr_read(6, ncr_dev); - else if (addr >= 0x1de0 && addr < 0x1e00) - ret = ncr_read(7, ncr_dev); + ret = ncr_read((addr - 0x1d00) >> 5, ncr_dev); } else if (addr >= 0x1e00 && addr < 0x2000) { if (ncr_dev->t128.host_pos >= MIN(512, dev->buffer_length) || ncr->dma_mode != DMA_INITIATOR_RECEIVE) { ret = 0xff; @@ -1408,24 +1393,9 @@ t128_write(uint32_t addr, uint8_t val, void *priv) } ncr_dev->t128.ctrl = val; ncr_log("T128 ctrl write = %02x\n", val); - } else if (addr >= 0x1d00 && addr < 0x1e00) { - if (addr >= 0x1d00 && addr < 0x1d20) - ncr_write(0, val, ncr_dev); - else if (addr >= 0x1d20 && addr < 0x1d40) - ncr_write(1, val, ncr_dev); - else if (addr >= 0x1d40 && addr < 0x1d60) - ncr_write(2, val, ncr_dev); - else if (addr >= 0x1d60 && addr < 0x1d80) - ncr_write(3, val, ncr_dev); - else if (addr >= 0x1d80 && addr < 0x1da0) - ncr_write(4, val, ncr_dev); - else if (addr >= 0x1da0 && addr < 0x1dc0) - ncr_write(5, val, ncr_dev); - else if (addr >= 0x1dc0 && addr < 0x1de0) - ncr_write(6, val, ncr_dev); - else if (addr >= 0x1de0 && addr < 0x1e00) - ncr_write(7, val, ncr_dev); - } else if (addr >= 0x1e00 && addr < 0x2000) { + } else if (addr >= 0x1d00 && addr < 0x1e00) + ncr_write((addr - 0x1d00) >> 5, val, ncr_dev); + else if (addr >= 0x1e00 && addr < 0x2000) { if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length) && ncr->dma_mode == DMA_SEND) { ncr_dev->t128.buffer[ncr_dev->t128.host_pos] = val; ncr_dev->t128.host_pos++; diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 53d37c9d8..dfeae7569 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -1,25 +1,25 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the NCR 53C810 and 53C875 SCSI Host - * Adapters made by NCR and later Symbios and LSI. These - * controllers were designed for the PCI bus. + * Implementation of the NCR 53C810 and 53C875 SCSI Host + * Adapters made by NCR and later Symbios and LSI. These + * controllers were designed for the PCI bus. * * * - * Authors: Paul Brook (QEMU) - * Artyom Tarasenko (QEMU) - * TheCollector1995, - * Miran Grca, + * Authors: Paul Brook (QEMU) + * Artyom Tarasenko (QEMU) + * TheCollector1995, + * Miran Grca, * - * Copyright 2006-2018 Paul Brook. - * Copyright 2009-2018 Artyom Tarasenko. - * Copyright 2017,2018 Miran Grca. + * Copyright 2006-2018 Paul Brook. + * Copyright 2009-2018 Artyom Tarasenko. + * Copyright 2017-2018 Miran Grca. */ #include #include @@ -877,8 +877,8 @@ ncr53c8xx_bad_message(ncr53c8xx_t *dev, uint8_t msg) static void ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id) { - uint8_t msg; - int len, arg; + uint8_t msg; + int len, arg; scsi_device_t *sd; sd = &scsi_devices[dev->bus][id]; @@ -2611,7 +2611,7 @@ static const device_config_t ncr53c8xx_pci_config[] = { }, }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t ncr53c810_pci_device = { diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 9fe6ee04c..c4f3143e8 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -1,25 +1,24 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the Tekram DC-390 SCSI and related MCA - * controllers using the NCR 53c9x series of chips. + * Implementation of the Tekram DC-390 SCSI and related MCA + * controllers using the NCR 53c9x series of chips. * * * + * Authors: Fabrice Bellard (QEMU) + * Herve Poussineau (QEMU) + * TheCollector1995, + * Miran Grca, * - * Authors: Fabrice Bellard (QEMU) - * Herve Poussineau (QEMU) - * TheCollector1995, - * Miran Grca, - * - * Copyright 2005-2018 Fabrice Bellard. - * Copyright 2012-2018 Herve Poussineau. - * Copyright 2017,2018 Miran Grca. + * Copyright 2005-2018 Fabrice Bellard. + * Copyright 2012-2018 Herve Poussineau. + * Copyright 2017-2018 Miran Grca. */ #include #include @@ -519,8 +518,7 @@ esp_dma_enable(esp_t *dev, int level) dev->dma_enabled = 1; dev->dma_86c01.status |= 0x02; timer_stop(&dev->timer); - if (((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) && - ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_PAD)) { + if (((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) && ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_PAD)) { timer_on_auto(&dev->timer, 40.0); } else { esp_log("Period = %lf\n", dev->period); @@ -1661,7 +1659,7 @@ esp_pci_read(int func, int addr, void *p) case 0x0E: return 0; /*Header type */ case 0x10: - return (esp_pci_bar[0].addr_regs[1] & 0x80) | 0x01; /*I/O space*/ + return (esp_pci_bar[0].addr_regs[0] & 0x80) | 0x01; /*I/O space*/ case 0x11: return esp_pci_bar[0].addr_regs[1]; case 0x12: @@ -1822,12 +1820,14 @@ dc390_init(const device_t *info) esp_pci_regs[0x04] = 3; dev->has_bios = device_get_config_int("bios"); - if (dev->has_bios) - rom_init(&dev->bios, DC390_ROM, 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (dev->has_bios) { + dev->BIOSBase = 0xd0000; + rom_init(&dev->bios, DC390_ROM, 0xd0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + } /* Enable our BIOS space in PCI, if needed. */ if (dev->has_bios) { - esp_pci_bar[1].addr = 0xfff80000; + esp_pci_bar[1].addr = 0xffff0000; } else { esp_pci_bar[1].addr = 0; } @@ -2038,7 +2038,7 @@ static const device_config_t bios_enable_config[] = { .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t dc390_pci_device = { diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index 799be48d0..ab970f17a 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the IBM PS/2 SCSI controller with - * cache for MCA only. + * Implementation of the IBM PS/2 SCSI controller with + * cache for MCA only. * * * - * Authors: Sarah Walker, - * TheCollector1995, + * Authors: Sarah Walker, + * TheCollector1995, * - * Copyright 2020 Sarah Walker. - * Copyright 2020 TheCollector1995. + * Copyright 2020 Sarah Walker. + * Copyright 2020 TheCollector1995. */ #include #include @@ -1175,7 +1175,7 @@ static const device_config_t spock_rom_config[] = { }, }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t spock_device = { diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 4cfcd49b2..45854a0ba 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -1,24 +1,24 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the code common to the AHA-154x series of - * SCSI Host Adapters made by Adaptec, Inc. and the BusLogic - * series of SCSI Host Adapters made by Mylex. - * These controllers were designed for various buses. + * Implementation of the code common to the AHA-154x series of + * SCSI Host Adapters made by Adaptec, Inc. and the BusLogic + * series of SCSI Host Adapters made by Mylex. + * These controllers were designed for various buses. * * * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, + * Authors: TheCollector1995, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017-2018 Fred N. van Kempen. */ #include #include @@ -1402,7 +1402,7 @@ x54x_reset(x54x_t *dev) clear_irq(dev); if (dev->flags & X54X_INT_GEOM_WRITABLE) - dev->Geometry = 0x80; + dev->Geometry = 0x90; else dev->Geometry = 0x00; dev->callback_phase = 0; diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 5017295b1..bf38efe57 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(sio OBJECT sio_acc3221.c sio_ali5123.c sio_f82c710.c sio_82091aa.c diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index 609a51e4b..9484ae680 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation of the SMC FDC37C663 and FDC37C665 Super - * I/O Chips. + * Implementation of the SMC FDC37C663 and FDC37C665 Super + * I/O Chips. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 3f646a55f..66672d547 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -1,23 +1,24 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_resid.cc midi.c snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_via.c snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c - snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c) + snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c + snd_optimc.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/midi.c b/src/sound/midi.c index d64c8c268..93fa62891 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -172,7 +172,7 @@ midi_out_device_get_from_internal_name(char *s) } void -midi_out_device_init() +midi_out_device_init(void) { if (devices[midi_output_device_current].device) device_add(devices[midi_output_device_current].device); @@ -290,7 +290,7 @@ midi_in_device_get_from_internal_name(char *s) } void -midi_in_device_init() +midi_in_device_init(void) { if (midi_in_devices[midi_input_device_current].device) device_add(midi_in_devices[midi_input_device_current].device); diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index ca0d3e866..4336670c6 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -244,7 +244,7 @@ fluidsynth_init(const device_t *info) fluidsynth_handle = dynld_module("libfluidsynth.so.2", fluidsynth_imports); # endif if (fluidsynth_handle == NULL) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2080, (wchar_t *) IDS_2133); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2080, (wchar_t *) IDS_2134); return NULL; } @@ -563,4 +563,4 @@ const device_t fluidsynth_device = { .config = fluidsynth_config }; -#endif/*USE_FLUIDSYNTH*/ +#endif /*USE_FLUIDSYNTH*/ diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index 79590230f..80b49112f 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -119,7 +119,7 @@ mt32_check(const char *func, mt32emu_return_code ret, mt32emu_return_code expect } int -mt32_old_available() +mt32_old_available(void) { if (roms_present[0] < 0) roms_present[0] = (rom_present(MT32_OLD_CTRL_ROM) && rom_present(MT32_OLD_PCM_ROM)); @@ -127,7 +127,7 @@ mt32_old_available() } int -mt32_new_available() +mt32_new_available(void) { if (roms_present[0] < 0) roms_present[0] = (rom_present(MT32_NEW_CTRL_ROM) && rom_present(MT32_NEW_PCM_ROM)); @@ -135,7 +135,7 @@ mt32_new_available() } int -cm32l_available() +cm32l_available(void) { if (roms_present[1] < 0) roms_present[1] = (rom_present(CM32L_CTRL_ROM) && rom_present(CM32L_PCM_ROM)); @@ -143,7 +143,7 @@ cm32l_available() } int -cm32ln_available() +cm32ln_available(void) { if (roms_present[1] < 0) roms_present[1] = (rom_present(CM32LN_CTRL_ROM) && rom_present(CM32LN_PCM_ROM)); @@ -199,7 +199,7 @@ mt32_stream_int16(int16_t *stream, int len) } void -mt32_poll() +mt32_poll(void) { midi_pos++; if (midi_pos == 48000 / RENDER_RATE) { @@ -416,7 +416,7 @@ static const device_config_t mt32_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mt32_old_device = { diff --git a/src/sound/midi_rtmidi.cpp b/src/sound/midi_rtmidi.cpp index bffd0a8f2..743b828ad 100644 --- a/src/sound/midi_rtmidi.cpp +++ b/src/sound/midi_rtmidi.cpp @@ -272,7 +272,7 @@ static const device_config_t midi_input_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t rtmidi_output_device = { diff --git a/src/sound/munt/CMakeLists.txt b/src/sound/munt/CMakeLists.txt index 3ebbe40fa..37d9e07cc 100644 --- a/src/sound/munt/CMakeLists.txt +++ b/src/sound/munt/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(mt32emu STATIC Analog.cpp BReverbModel.cpp Display.cpp File.cpp FileStream.cpp diff --git a/src/sound/resid-fp/CMakeLists.txt b/src/sound/resid-fp/CMakeLists.txt index fb9b5396e..5ec9130d7 100644 --- a/src/sound/resid-fp/CMakeLists.txt +++ b/src/sound/resid-fp/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(resid-fp STATIC convolve-sse.cc convolve.cc envelope.cc extfilt.cc diff --git a/src/sound/snd_ac97_codec.c b/src/sound/snd_ac97_codec.c index 54aabab2e..58422a288 100644 --- a/src/sound/snd_ac97_codec.c +++ b/src/sound/snd_ac97_codec.c @@ -637,7 +637,7 @@ ac97_codec_get(int model) if ((model >= 0) && (model < (sizeof(ac97_codecs) / sizeof(ac97_codecs[0])))) return ac97_codecs[model].device; else - return &cs4297a_device;/* fallback */ + return &cs4297a_device; /* fallback */ } const device_t ad1881_device = { diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index bf3858aa3..558024fb5 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -378,24 +378,27 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 25: return; + case 27: + if (ad1848->type != AD1848_TYPE_DEFAULT) + return; + break; } ad1848->regs[ad1848->index] = val; if (updatefreq) ad1848_updatefreq(ad1848); - if (ad1848->type >= AD1848_TYPE_CS4231) { /* TODO: configure CD volume for CS4248/AD1848 too */ - temp = (ad1848->type == AD1848_TYPE_CS4231) ? 18 : 4; - if (ad1848->regs[temp] & 0x80) - ad1848->cd_vol_l = 0; - else - ad1848->cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; - temp++; - if (ad1848->regs[temp] & 0x80) - ad1848->cd_vol_r = 0; - else - ad1848->cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; - } + temp = (ad1848->type < AD1848_TYPE_CS4231) ? 2 : ((ad1848->type == AD1848_TYPE_CS4231) ? 18 : 4); + if (ad1848->regs[temp] & 0x80) + ad1848->cd_vol_l = 0; + else + ad1848->cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; + temp++; + if (ad1848->regs[temp] & 0x80) + ad1848->cd_vol_r = 0; + else + ad1848->cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; + break; case 2: @@ -599,6 +602,24 @@ ad1848_filter_cd_audio(int channel, double *buffer, void *priv) *buffer = c; } +void +ad1848_filter_aux2(void *priv, double *out_l, double *out_r) +{ + ad1848_t *ad1848 = (ad1848_t *) priv; + + if (ad1848->regs[4] & 0x80) { + *out_l = 0.0; + } else { + *out_l = ((*out_l) * ad1848_vols_5bits_aux_gain[ad1848->regs[4] & 0x1f]) / 65536.0; + } + + if (ad1848->regs[5] & 0x80) { + *out_r = 0.0; + } else { + *out_r = ((*out_r) * ad1848_vols_5bits_aux_gain[ad1848->regs[5] & 0x1f]) / 65536.0; + } +} + void ad1848_init(ad1848_t *ad1848, uint8_t type) { diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index c07bc52e4..0616e8fa6 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -131,7 +131,7 @@ static int treble_cut[6] = { (int) (0.354 * 16384) /*-3 dB - filter output is at +6 dB*/ }; -void adgold_timer_poll(); +void adgold_timer_poll(void *p); void adgold_update(adgold_t *adgold); void @@ -1076,7 +1076,7 @@ static const device_config_t adgold_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t adgold_device = { diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 7a72d0ef0..b02243855 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -2099,7 +2099,7 @@ static const device_config_t es1371_onboard_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t es1371_device = { diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index bb497e3f2..ee46ab01b 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -891,15 +891,12 @@ azt_init(const device_t *info) azt2316a_t *azt2316a = malloc(sizeof(azt2316a_t)); memset(azt2316a, 0, sizeof(azt2316a_t)); - azt2316a->type = info->local & 0x7fffffff; + azt2316a->type = info->local; if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { fn = "azt1605.nvr"; } else if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { - if (info->local & 0x80000000) - fn = "acermagic_s20.nvr"; - else - fn = "azt2316a.nvr"; + fn = "azt2316a.nvr"; } /* config */ @@ -985,9 +982,7 @@ azt_init(const device_t *info) else fatal("AZT2316A: invalid sb irq in config word %08X\n", azt2316a->config_word); - if (info->local & 0x80000000) - azt2316a->cur_dma = 1; - else switch (azt2316a->config_word & (3 << 6)) { + switch (azt2316a->config_word & (3 << 6)) { case 1 << 6: azt2316a->cur_dma = 0; break; @@ -1117,10 +1112,7 @@ azt_init(const device_t *info) azt2316a->cur_wss_enabled = 0; // these are not present on the EEPROM - if (info->local & 0x80000000) - azt2316a->cur_dma = 1; - else - azt2316a->cur_dma = device_get_config_int("sb_dma8"); // TODO: investigate TSR to make this work with it - there is no software configurable DMA8? + azt2316a->cur_dma = device_get_config_int("sb_dma8"); // TODO: investigate TSR to make this work with it - there is no software configurable DMA8? azt2316a->cur_wss_irq = device_get_config_int("wss_irq"); azt2316a->cur_wss_dma = device_get_config_int("wss_dma"); azt2316a->cur_mode = 0; @@ -1133,10 +1125,7 @@ azt_init(const device_t *info) azt2316a->wss_interrupt_after_config = device_get_config_int("wss_interrupt_after_config"); /* wss part */ - if (info->local & 0x80000000) - ad1848_init(&azt2316a->ad1848, AD1848_TYPE_CS4231); - else - ad1848_init(&azt2316a->ad1848, device_get_config_int("codec")); + ad1848_init(&azt2316a->ad1848, device_get_config_int("codec")); ad1848_setirq(&azt2316a->ad1848, azt2316a->cur_wss_irq); ad1848_setdma(&azt2316a->ad1848, azt2316a->cur_wss_dma); @@ -1225,6 +1214,7 @@ azt_close(void *p) sb_close(azt2316a->sb); + free(azt2316a->mpu); free(azt2316a); } @@ -1499,89 +1489,7 @@ static const device_config_t azt2316a_config[] = { .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on -}; - -static const device_config_t acermagic_s20_config[] = { - // clang-format off - { - .name = "wss_interrupt_after_config", - .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "addr", - .description = "SB Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "Use EEPROM setting", - .value = 0 - }, - { - .description = "" - } - } - }, - { - .name = "wss_irq", - .description = "WSS IRQ", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "" - } - }, - .default_int = 10 - }, - { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 - }, - { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 - }, - { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 - }, - { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t azt2316a_device = { @@ -1598,20 +1506,6 @@ const device_t azt2316a_device = { .config = azt2316a_config }; -const device_t acermagic_s20_device = { - .name = "AcerMagic S20", - .internal_name = "acermagic_s20", - .flags = DEVICE_ISA | DEVICE_AT, - .local = SB_SUBTYPE_CLONE_AZT2316A_0X11 | 0x80000000, - .init = azt_init, - .close = azt_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = azt_speed_changed, - .force_redraw = NULL, - .config = acermagic_s20_config -}; - const device_t azt1605_device = { .name = "Aztech Sound Galaxy Nova 16 Extra (Clinton)", .internal_name = "azt1605", diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index 034fa9bcf..d4a54880b 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -1474,7 +1474,7 @@ static const device_config_t cmi8738_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t cmi8338_device = { diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index 2014080c6..1b55765fa 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -227,7 +227,7 @@ static const device_config_t cms_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t cms_device = { diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index dceabdd08..0a98d9886 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -57,7 +57,7 @@ static const uint8_t slam_init_key[32] = { 0x96, 0x35, 0x9A, 0xCD, 0xE6, 0xF3, 0 0xF1, 0xF8, 0x7C, 0x3E, 0x9F, 0x4F, 0x27, 0x13, 0x09, 0x84, 0x42, 0xA1, 0xD0, 0x68, 0x34, 0x1A }; static const uint8_t cs4236b_eeprom[] = { - // clang-format off + // clang-format off /* Chip configuration */ 0x55, 0xbb, /* magic */ 0x00, 0x00, /* length */ diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 33e80fb31..528a3ad50 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -19,17 +19,17 @@ #include <86box/timer.h> #if !defined FILTER_INITIAL && !defined FILTER_MOOG && !defined FILTER_CONSTANT -//#define FILTER_INITIAL +// #define FILTER_INITIAL # define FILTER_MOOG -//#define FILTER_CONSTANT +// #define FILTER_CONSTANT #endif #if !defined RESAMPLER_LINEAR && !defined RESAMPLER_CUBIC -//#define RESAMPLER_LINEAR +// #define RESAMPLER_LINEAR # define RESAMPLER_CUBIC #endif -//#define EMU8K_DEBUG_REGISTERS +// #define EMU8K_DEBUG_REGISTERS char *PORT_NAMES[][8] = { /* Data 0 ( 0x620/0x622) */ diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index 074a1396f..a31c48a7b 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -1958,7 +1958,7 @@ static const device_config_t mpu401_standalone_mca_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mpu401_device = { diff --git a/src/sound/snd_opl.c b/src/sound/snd_opl.c index 409467725..21cc66f04 100644 --- a/src/sound/snd_opl.c +++ b/src/sound/snd_opl.c @@ -64,6 +64,11 @@ fm_driver_get(int chip_id, fm_drv_t *drv) drv->priv = device_add_inst(&ymf289b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); break; + case FM_YMF278B: + *drv = ymfm_drv; + drv->priv = device_add_inst(&ymf278b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + default: return 0; } diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index 437ae8bc3..3c0d22131 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -221,7 +221,7 @@ nuked_log(const char *fmt, ...) va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); - } + } } #else # define nuked_log(fmt, ...) diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index 1e9f5f9b5..bb52f3c55 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -27,6 +27,8 @@ extern "C" { #include <86box/device.h> #include <86box/sound.h> #include <86box/snd_opl.h> +#include <86box/mem.h> +#include <86box/rom.h> } #define RSM_FRAC 10 @@ -62,6 +64,7 @@ public: virtual void generate_resampled(int32_t *data, uint32_t num_samples) = 0; virtual int32_t *update() = 0; virtual uint8_t read(uint16_t addr) = 0; + virtual void set_clock(uint32_t clock) = 0; protected: int32_t m_buffer[SOUNDBUFLEN * 2]; @@ -77,6 +80,7 @@ public: : YMFMChipBase(clock, type, samplerate) , m_chip(*this) , m_clock(clock) + , m_samplerate(samplerate) , m_samplecnt(0) { memset(m_samples, 0, sizeof(m_samples)); @@ -87,6 +91,12 @@ public: m_subtract[1] = 320.0; m_type = type; + if (m_type == FM_YMF278B) { + if (rom_load_linear("roms/sound/yamaha/yrw801.rom", 0, 0x200000, 0, m_yrw801) == 0) { + fatal("YRW801 ROM image \"roms/sound/yamaha/yrw801.rom\" not found\n"); + } + } + timer_add(&m_timers[0], YMFMChip::timer1, this, 0); timer_add(&m_timers[1], YMFMChip::timer2, this, 0); } @@ -101,7 +111,8 @@ public: if (tnum > 1) return; - pc_timer_t *timer = &m_timers[tnum]; + m_duration_in_clocks[tnum] = duration_in_clocks; + pc_timer_t *timer = &m_timers[tnum]; if (duration_in_clocks < 0) timer_stop(timer); else { @@ -113,16 +124,26 @@ public: } } + virtual void set_clock(uint32_t clock) override + { + m_clock = clock; + m_clock_us = 1000000 / (double) m_clock; + m_rateratio = (m_samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock); + + ymfm_set_timer(0, m_duration_in_clocks[0]); + ymfm_set_timer(1, m_duration_in_clocks[1]); + } + virtual void generate(int32_t *data, uint32_t num_samples) override { for (uint32_t i = 0; i < num_samples; i++) { m_chip.generate(&m_output); if (ChipType::OUTPUTS == 1) { - *data++ = m_output.data[0]; - *data++ = m_output.data[0]; + *data++ = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; + *data++ = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; } else { - *data++ = m_output.data[0]; - *data++ = m_output.data[1 % ChipType::OUTPUTS]; + *data++ = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; + *data++ = m_output.data[(m_type == FM_YMF278B) ? 5 : (1 % ChipType::OUTPUTS)]; } } } @@ -135,11 +156,11 @@ public: m_oldsamples[1] = m_samples[1]; m_chip.generate(&m_output); if (ChipType::OUTPUTS == 1) { - m_samples[0] = m_output.data[0]; - m_samples[1] = m_output.data[0]; + m_samples[0] = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; + m_samples[1] = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; } else { - m_samples[0] = m_output.data[0]; - m_samples[1] = m_output.data[1 % ChipType::OUTPUTS]; + m_samples[0] = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; + m_samples[1] = m_output.data[(m_type == FM_YMF278B) ? 5 : (1 % ChipType::OUTPUTS)]; } m_samplecnt -= m_rateratio; } @@ -182,7 +203,7 @@ public: virtual uint32_t get_special_flags(void) override { - return ((m_type == FM_YMF262) || (m_type == FM_YMF289B)) ? 0x8000 : 0x0000; + return ((m_type == FM_YMF262) || (m_type == FM_YMF289B) || (m_type == FM_YMF278B)) ? 0x8000 : 0x0000; } static void timer1(void *priv) @@ -197,12 +218,25 @@ public: drv->m_engine->engine_timer_expired(1); } + virtual uint8_t ymfm_external_read(ymfm::access_class type, uint32_t address) override + { + if (type == ymfm::access_class::ACCESS_PCM && address < 0x200000) { + return m_yrw801[address]; + } + return 0xFF; + } + private: ChipType m_chip; uint32_t m_clock; double m_clock_us, m_subtract[2]; typename ChipType::output_data m_output; pc_timer_t m_timers[2]; + int32_t m_duration_in_clocks[2]; // Needed for clock switches. + uint32_t m_samplerate; + + // YRW801-M wavetable ROM. + uint8_t m_yrw801[0x200000]; // Resampling int32_t m_rateratio; @@ -237,7 +271,7 @@ ymfm_log(const char *fmt, ...) va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); - } + } } #else # define ymfm_log(fmt, ...) @@ -261,6 +295,10 @@ ymfm_drv_init(const device_t *info) case FM_YMF289B: fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF289B, 48000); break; + + case FM_YMF278B: + fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, 48000); + break; } fm->set_do_cycles(1); @@ -282,9 +320,12 @@ ymfm_drv_read(uint16_t port, void *priv) { YMFMChipBase *drv = (YMFMChipBase *) priv; - if (drv->flags() & FLAG_CYCLES) { + if ((port == 0x380) || (port == 0x381)) + port |= 4; + + /* Point to register read port. */ + if (drv->flags() & FLAG_CYCLES) cycles -= ((int) (isa_timing * 8)); - } uint8_t ret = drv->read(port); drv->update(); @@ -298,6 +339,8 @@ ymfm_drv_write(uint16_t port, uint8_t val, void *priv) { YMFMChipBase *drv = (YMFMChipBase *) priv; ymfm_log("YMFM write port %04x value = %02x\n", port, val); + if ((port == 0x380) || (port == 0x381)) + port |= 4; drv->write(port, val); drv->update(); } @@ -367,6 +410,20 @@ const device_t ymf289b_ymfm_device = { .config = NULL }; +const device_t ymf278b_ymfm_device = { + .name = "Yamaha YMF278B OPL4 (YMFM)", + .internal_name = "ymf289b_ymfm", + .flags = 0, + .local = FM_YMF278B, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const fm_drv_t ymfm_drv { &ymfm_drv_read, &ymfm_drv_write, diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c new file mode 100644 index 000000000..b54174ce0 --- /dev/null +++ b/src/sound/snd_optimc.c @@ -0,0 +1,473 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * OPTi MediaCHIPS 82C929 (also known as OPTi MAD16 Pro) audio controller emulation. + * + * + * + * Authors: Cacodemon345 + * Eluan Costa Miranda + * + * Copyright 2022 Cacodemon345. + * Copyright 2020 Eluan Costa Miranda. + */ + +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/midi.h> +#include <86box/timer.h> +#include <86box/nvr.h> +#include <86box/pic.h> +#include <86box/sound.h> +#include <86box/gameport.h> +#include <86box/snd_ad1848.h> +#include <86box/snd_sb.h> +#include <86box/mem.h> +#include <86box/rom.h> + +static int optimc_wss_dma[4] = { 0, 0, 1, 3 }; +static int optimc_wss_irq[8] = { 5, 7, 9, 10, 11, 12, 14, 15 }; /* W95 only uses 7-10, others may be wrong */ + +enum optimc_local_flags { + OPTIMC_CS4231 = 0x100, + OPTIMC_OPL4 = 0x200, +}; + +typedef struct optimc_t { + uint8_t type, fm_type; + + uint8_t wss_config, reg_enabled; + + uint16_t cur_addr, cur_wss_addr, cur_mpu401_addr; + + int cur_irq, cur_dma; + int cur_wss_enabled, cur_wss_irq, cur_wss_dma; + int cur_mpu401_irq; + int cur_mpu401_enabled; + void *gameport; + + uint8_t cur_mode; + + ad1848_t ad1848; + mpu_t *mpu; + + sb_t *sb; + uint8_t regs[6]; +} optimc_t, opti_82c929_t; + +static void +optimc_filter_opl(void* priv, double* out_l, double* out_r) +{ + optimc_t *optimc = (optimc_t *) priv; + + if (optimc->cur_wss_enabled) { + *out_l /= optimc->sb->mixer_sbpro.fm_l; + *out_r /= optimc->sb->mixer_sbpro.fm_r; + ad1848_filter_aux2((void*)&optimc->ad1848, out_l, out_r); + } +} + +static uint8_t +optimc_wss_read(uint16_t addr, void *priv) +{ + optimc_t *optimc = (optimc_t *) priv; + + if (!(optimc->regs[4] & 0x10) && optimc->cur_mode == 0) + return 0xFF; + + return 4 | (optimc->wss_config & 0x40); +} + +static void +optimc_wss_write(uint16_t addr, uint8_t val, void *priv) +{ + optimc_t *optimc = (optimc_t *) priv; + + if (!(optimc->regs[4] & 0x10) && optimc->cur_mode == 0) + return; + optimc->wss_config = val; + ad1848_setdma(&optimc->ad1848, optimc_wss_dma[val & 3]); + ad1848_setirq(&optimc->ad1848, optimc_wss_irq[(val >> 3) & 7]); +} + +static void +optimc_get_buffer(int32_t *buffer, int len, void *p) +{ + optimc_t *optimc = (optimc_t *) p; + int c; + + if (optimc->regs[3] & 0x4) + return; + + /* wss part */ + ad1848_update(&optimc->ad1848); + for (c = 0; c < len * 2; c++) + buffer[c] += (optimc->ad1848.buffer[c] / 2); + + optimc->ad1848.pos = 0; + + /* sbprov2 part */ + sb_get_buffer_sbpro(buffer, len, optimc->sb); +} + +static void +optimc_remove_opl(optimc_t *optimc) +{ + io_removehandler(optimc->cur_addr + 0, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); + io_removehandler(optimc->cur_addr + 8, 0x0002, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); + io_removehandler(0x0388, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); +} + +static void +optimc_add_opl(optimc_t *optimc) +{ + /* DSP I/O handler is activated in sb_dsp_setaddr */ + io_sethandler(optimc->cur_addr + 0, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); + io_sethandler(optimc->cur_addr + 8, 0x0002, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); + io_sethandler(0x0388, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); +} + +static void +optimc_reg_write(uint16_t addr, uint8_t val, void *p) +{ + optimc_t *optimc = (optimc_t *) p; + uint16_t idx = addr - 0xF8D; + uint8_t old = optimc->regs[idx]; + static uint8_t reg_enable_phase = 0; + + if (optimc->reg_enabled) { + switch (idx) { + case 0: /* MC1 */ + optimc->regs[0] = val; + if (val != old) { + optimc->cur_mode = optimc->cur_wss_enabled = !!(val & 0x80); + + sound_set_cd_audio_filter(NULL, NULL); + if (optimc->cur_wss_enabled) /* WSS */ + sound_set_cd_audio_filter(ad1848_filter_cd_audio, &optimc->ad1848); + else /* SBPro */ + sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); + + io_removehandler(optimc->cur_wss_addr, 0x0004, optimc_wss_read, NULL, NULL, optimc_wss_write, NULL, NULL, optimc); + io_removehandler(optimc->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &optimc->ad1848); + switch ((val >> 4) & 0x3) { + case 0: /* WSBase = 0x530 */ + optimc->cur_wss_addr = 0x530; + break; + case 1: /* WSBase = 0xE80 */ + optimc->cur_wss_addr = 0xE80; + break; + case 2: /* WSBase = 0xF40 */ + optimc->cur_wss_addr = 0xF40; + break; + case 3: /* WSBase = 0x604 */ + optimc->cur_wss_addr = 0x604; + break; + } + io_sethandler(optimc->cur_wss_addr, 0x0004, optimc_wss_read, NULL, NULL, optimc_wss_write, NULL, NULL, optimc); + io_sethandler(optimc->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &optimc->ad1848); + + gameport_remap(optimc->gameport, (optimc->regs[0] & 0x1) ? 0x00 : 0x200); + } + break; + case 1: /* MC2 */ + optimc->regs[1] = val; + break; + case 2: /* MC3 */ + if (val == optimc->type) + break; + optimc->regs[2] = val; + if (old != val) { + io_removehandler(optimc->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, optimc->sb); + optimc_remove_opl(optimc); + optimc->cur_addr = (val & 0x4) ? 0x240 : 0x220; + switch ((val >> 4) & 0x3) { + case 0: + optimc->cur_dma = 1; + break; + case 1: + optimc->cur_dma = 0; + break; + case 2: + default: + optimc->cur_dma = 3; + break; + } + switch ((val >> 6) & 0x3) { + case 0: + optimc->cur_irq = 7; + break; + case 1: + optimc->cur_irq = 10; + break; + case 2: + default: + optimc->cur_irq = 5; + break; + } + sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr); + sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq); + sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma); + optimc_add_opl(optimc); + io_sethandler(optimc->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, optimc->sb); + } + break; + case 3: /* MC4 */ + optimc->regs[3] = val; + break; + case 4: /* MC5 */ + optimc->regs[4] = val; + break; + case 5: /* MC6 */ + optimc->regs[5] = val; + if (old != val) { + switch ((val >> 3) & 0x3) { + case 0: + optimc->cur_mpu401_irq = 9; + break; + case 1: + optimc->cur_mpu401_irq = 10; + break; + case 2: + optimc->cur_mpu401_irq = 5; + break; + case 3: + optimc->cur_mpu401_irq = 7; + break; + } + switch ((val >> 5) & 0x3) { + case 0: + optimc->cur_mpu401_addr = 0x330; + break; + case 1: + optimc->cur_mpu401_addr = 0x320; + break; + case 2: + optimc->cur_mpu401_addr = 0x310; + break; + case 3: + optimc->cur_mpu401_addr = 0x300; + break; + } + mpu401_change_addr(optimc->mpu, optimc->cur_mpu401_addr); + mpu401_setirq(optimc->mpu, optimc->cur_mpu401_irq); + } + break; + } + } + if (optimc->reg_enabled) + optimc->reg_enabled = 0; + if ((addr == 0xF8F) && ((val == optimc->type) || (val == 0x00))) { + if ((addr == 0xF8F) && (val == optimc->type) && !optimc->reg_enabled) + optimc->reg_enabled = 1; + if (reg_enable_phase) { + switch (reg_enable_phase) { + case 1: + if (val == optimc->type) { + reg_enable_phase++; + } + break; + case 2: + if (val == 0x00) { + reg_enable_phase++; + } + break; + case 3: + if (val == optimc->type) { + optimc->regs[2] = 0x2; + reg_enable_phase = 1; + } + break; + } + } else + reg_enable_phase = 1; + return; + } +} + +static uint8_t +optimc_reg_read(uint16_t addr, void *p) +{ + optimc_t *optimc = (optimc_t *) p; + uint8_t temp = 0xFF; + + if (optimc->reg_enabled) { + switch (addr - 0xF8D) { + case 0: /* MC1 */ + case 1: /* MC2 */ + case 3: /* MC4 */ + case 4: /* MC5 */ + case 5: /* MC6 */ + temp = optimc->regs[addr - 0xF8D]; + break; + case 2: /* MC3 */ + temp = (optimc->regs[2] & ~0x3) | 0x2; + break; + } + optimc->reg_enabled = 0; + } + return temp; +} + +static void * +optimc_init(const device_t *info) +{ + optimc_t *optimc = calloc(1, sizeof(optimc_t)); + + optimc->type = info->local & 0xFF; + + optimc->cur_wss_addr = 0x530; + optimc->cur_mode = 0; + optimc->cur_addr = 0x220; + optimc->cur_irq = 7; + optimc->cur_wss_enabled = 0; + optimc->cur_dma = 1; + optimc->cur_mpu401_irq = 9; + optimc->cur_mpu401_addr = 0x330; + optimc->cur_mpu401_enabled = 1; + + optimc->regs[0] = 0x00; + optimc->regs[1] = 0x03; + optimc->regs[2] = 0x00; + optimc->regs[3] = 0x00; + optimc->regs[4] = 0x3F; + optimc->regs[5] = 0x83; + + optimc->gameport = gameport_add(&gameport_pnp_device); + gameport_remap(optimc->gameport, (optimc->regs[0] & 0x1) ? 0x00 : 0x200); + + if (info->local & 0x100) + ad1848_init(&optimc->ad1848, AD1848_TYPE_CS4231); + else + ad1848_init(&optimc->ad1848, AD1848_TYPE_DEFAULT); + + ad1848_setirq(&optimc->ad1848, optimc->cur_wss_irq); + ad1848_setdma(&optimc->ad1848, optimc->cur_wss_dma); + + io_sethandler(0xF8D, 6, optimc_reg_read, NULL, NULL, optimc_reg_write, NULL, NULL, optimc); + + io_sethandler(optimc->cur_wss_addr, 0x0004, optimc_wss_read, NULL, NULL, optimc_wss_write, NULL, NULL, optimc); + io_sethandler(optimc->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &optimc->ad1848); + + optimc->sb = calloc(1, sizeof(sb_t)); + optimc->sb->opl_enabled = 1; + + sb_dsp_init(&optimc->sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, optimc); + sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr); + sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq); + sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma); + sb_ct1345_mixer_reset(optimc->sb); + + optimc->sb->opl_mixer = optimc; + optimc->sb->opl_mix = optimc_filter_opl; + + optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262; + fm_driver_get(optimc->fm_type, &optimc->sb->opl); + io_sethandler(optimc->cur_addr + 0, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); + io_sethandler(optimc->cur_addr + 8, 0x0002, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); + io_sethandler(0x0388, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); + if (optimc->fm_type == FM_YMF278B) + io_sethandler(0x380, 2, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); + + io_sethandler(optimc->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, optimc->sb); + + sound_add_handler(optimc_get_buffer, optimc); + sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); /* CD audio filter for the default context */ + + optimc->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + memset(optimc->mpu, 0, sizeof(mpu_t)); + mpu401_init(optimc->mpu, optimc->cur_mpu401_addr, optimc->cur_mpu401_irq, M_UART, device_get_config_int("receive_input401")); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &optimc->sb->dsp); + + return optimc; +} + +static void +optimc_close(void *p) +{ + optimc_t *optimc = (optimc_t *) p; + + sb_close(optimc->sb); + free(optimc->mpu); + free(p); +} + +static void +optimc_speed_changed(void *p) +{ + optimc_t *optimc = (optimc_t *) p; + + ad1848_speed_changed(&optimc->ad1848); + sb_speed_changed(optimc->sb); +} + +static int +mirosound_pcm10_available(void) +{ + return rom_present("roms/sound/yamaha/yrw801.rom"); +} + +static const device_config_t acermagic_s20_config[] = { + // clang-format off + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { + .name = "receive_input401", + .description = "Receive input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t acermagic_s20_device = { + .name = "AcerMagic S20", + .internal_name = "acermagic_s20", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0xE3 | OPTIMC_CS4231, + .init = optimc_init, + .close = optimc_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = optimc_speed_changed, + .force_redraw = NULL, + .config = acermagic_s20_config +}; + +const device_t mirosound_pcm10_device = { + .name = "miroSOUND PCM10", + .internal_name = "mirosound_pcm10", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0xE3 | OPTIMC_OPL4, + .init = optimc_init, + .close = optimc_close, + .reset = NULL, + { .available = mirosound_pcm10_available }, + .speed_changed = optimc_speed_changed, + .force_redraw = NULL, + .config = acermagic_s20_config +}; diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index 80ef93e05..8b493e030 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -272,7 +272,7 @@ static const device_config_t pssj_isa_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t pssj_device = { diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 53b360386..7660ace90 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -290,6 +290,9 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *p) } else { out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (sb->opl_mix && sb->opl_mixer) { + sb->opl_mix(sb->opl_mixer, &out_l, &out_r); + } } } @@ -2035,37 +2038,37 @@ sb_16_compat_init(const device_t *info) } static int -sb_awe32_available() +sb_awe32_available(void) { return rom_present("roms/sound/awe32.raw"); } static int -sb_32_pnp_available() +sb_32_pnp_available(void) { return sb_awe32_available() && rom_present("roms/sound/CT3600 PnP.BIN"); } static int -sb_awe32_pnp_available() +sb_awe32_pnp_available(void) { return sb_awe32_available() && rom_present("roms/sound/CT3980 PnP.BIN"); } static int -sb_awe64_value_available() +sb_awe64_value_available(void) { return sb_awe32_available() && rom_present("roms/sound/CT4520 PnP.BIN"); } static int -sb_awe64_available() +sb_awe64_available(void) { return sb_awe32_available() && rom_present("roms/sound/CT4520 PnP.BIN"); } static int -sb_awe64_gold_available() +sb_awe64_gold_available(void) { return sb_awe32_available() && rom_present("roms/sound/CT4540 PnP.BIN"); } diff --git a/src/sound/snd_sn76489.c b/src/sound/snd_sn76489.c index a29405429..3cbb44ec3 100644 --- a/src/sound/snd_sn76489.c +++ b/src/sound/snd_sn76489.c @@ -281,7 +281,7 @@ static const device_config_t tndy_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t sn76489_device = { diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index 5596868f2..8a325e5c3 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -264,7 +264,7 @@ static const device_config_t wss_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t wss_device = { diff --git a/src/sound/sound.c b/src/sound/sound.c index 1efdef79b..cda851137 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -110,6 +110,7 @@ static const SOUND_CARD sound_cards[] = { { &sound_none_device }, { &sound_internal_device }, { &acermagic_s20_device }, + { &mirosound_pcm10_device }, { &adlib_device }, { &adgold_device }, { &azt2316a_device }, diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index b26bb9c9f..dbe0215eb 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -107,7 +107,7 @@ static IXAudio2VoiceCallback callbacks = { &callbacksVtbl }; #endif void -inital() +inital(void) { #if defined(_WIN32) && !defined(USE_FAUDIO) if (xaudio2_handle == NULL) { @@ -182,7 +182,7 @@ inital() } void -closeal() +closeal(void) { if (!initialized) return; diff --git a/src/sound/ymfm/CMakeLists.txt b/src/sound/ymfm/CMakeLists.txt index 2041719ae..e1ff35369 100644 --- a/src/sound/ymfm/CMakeLists.txt +++ b/src/sound/ymfm/CMakeLists.txt @@ -1 +1,12 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# + add_library(ymfm STATIC ymfm_misc.cpp ymfm_opl.cpp ymfm_opm.cpp ymfm_opn.cpp ymfm_opq.cpp ymfm_opz.cpp ymfm_pcm.cpp ymfm_adpcm.cpp) \ No newline at end of file diff --git a/src/sound/ymfm/ymfm_pcm.h b/src/sound/ymfm/ymfm_pcm.h index 2022a69b9..b471fa611 100644 --- a/src/sound/ymfm/ymfm_pcm.h +++ b/src/sound/ymfm/ymfm_pcm.h @@ -212,8 +212,8 @@ public: uint32_t result = memory_address(); uint32_t newval = result + 1; m_regdata[0x05] = newval >> 0; - m_regdata[0x06] = newval >> 8; - m_regdata[0x07] = (newval >> 16) & 0x3f; + m_regdata[0x04] = newval >> 8; + m_regdata[0x03] = (newval >> 16) & 0x3f; return result; } diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 6d1c01a34..5301c9268 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -1,18 +1,18 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: Cacodemon345 -# David Hrdlička, +# Authors: Cacodemon345 +# David Hrdlička, # -# Copyright 2021 Cacodemon345. -# Copyright 2021 David Hrdlička. +# Copyright 2021 Cacodemon345. +# Copyright 2021 David Hrdlička. # add_library(plat OBJECT unix.c) diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index c6378dddf..414a38a96 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -15,7 +15,7 @@ %global romver v3.7 Name: 86Box -Version: 3.8 +Version: 3.11 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -117,5 +117,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Tue Aug 30 2022 Robert de Rooy 3.8-1 +* Fri Nov 18 2022 Robert de Rooy 3.11-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 21e84b16a..3cd4b9ba2 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -10,7 +10,7 @@ net.86box.86Box.desktop - + diff --git a/src/unix/macOSXGlue.m b/src/unix/macOSXGlue.m index b170dea5f..95deb545d 100644 --- a/src/unix/macOSXGlue.m +++ b/src/unix/macOSXGlue.m @@ -8,36 +8,39 @@ #import -void getDefaultROMPath(char* Path) +void +getDefaultROMPath(char *Path) { - NSFileManager* sharedFM = [NSFileManager defaultManager]; - NSArray* possibleURLs = [sharedFM URLsForDirectory:NSApplicationSupportDirectory - inDomains:NSUserDomainMask]; - NSURL* appSupportDir = nil; - NSURL* appDirectory = nil; + NSFileManager *sharedFM = [NSFileManager defaultManager]; + NSArray *possibleURLs = [sharedFM URLsForDirectory:NSApplicationSupportDirectory + inDomains:NSUserDomainMask]; + NSURL *appSupportDir = nil; + NSURL *appDirectory = nil; - if ([possibleURLs count] >= 1) { - // Use the first directory (if multiple are returned) - appSupportDir = [possibleURLs objectAtIndex:0]; - } + if ([possibleURLs count] >= 1) { + // Use the first directory (if multiple are returned) + appSupportDir = [possibleURLs objectAtIndex:0]; + } - // If a valid app support directory exists, add the - // app's bundle ID to it to specify the final directory. - if (appSupportDir) { - NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier]; - appDirectory = [appSupportDir URLByAppendingPathComponent:appBundleID]; - appDirectory=[appDirectory URLByAppendingPathComponent:@"roms"]; - } + // If a valid app support directory exists, add the + // app's bundle ID to it to specify the final directory. + if (appSupportDir) { + NSString *appBundleID = [[NSBundle mainBundle] bundleIdentifier]; + appDirectory = [appSupportDir URLByAppendingPathComponent:appBundleID]; + appDirectory = [appDirectory URLByAppendingPathComponent:@"roms"]; + } // create ~/Library/Application Support/... stuff - NSError* theError = nil; - if (![sharedFM createDirectoryAtURL:appDirectory withIntermediateDirectories:YES - attributes:nil error:&theError]) - { - // Handle the error. - NSLog(@"Error creating user library rom path"); - } else NSLog(@"Create user rom path sucessfull"); + NSError *theError = nil; + if (![sharedFM createDirectoryAtURL:appDirectory + withIntermediateDirectories:YES + attributes:nil + error:&theError]) { + // Handle the error. + NSLog(@"Error creating user library rom path"); + } else + NSLog(@"Create user rom path sucessfull"); - strcpy(Path,[appDirectory fileSystemRepresentation]); - // return appDirectory; + strcpy(Path, [appDirectory fileSystemRepresentation]); + // return appDirectory; } diff --git a/src/unix/unix.c b/src/unix/unix.c index acd81c1f9..4410118f3 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -244,37 +244,37 @@ plat_get_string(int i) return L"Press CTRL-END or middle button to release mouse"; case IDS_2080: return L"Failed to initialize FluidSynth"; - case IDS_2130: + case IDS_2131: return L"Invalid configuration"; case IDS_4099: return L"MFM/RLL or ESDI CD-ROM drives never existed"; - case IDS_2093: - return L"Failed to set up PCap"; case IDS_2094: - return L"No PCap devices found"; + return L"Failed to set up PCap"; case IDS_2095: + return L"No PCap devices found"; + case IDS_2096: return L"Invalid PCap device"; - case IDS_2110: - return L"Unable to initialize FreeType"; case IDS_2111: + return L"Unable to initialize FreeType"; + case IDS_2112: return L"Unable to initialize SDL, libsdl2 is required"; - case IDS_2131: - return L"libfreetype is required for ESC/P printer emulation."; case IDS_2132: - return L"libgs is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."; + return L"libfreetype is required for ESC/P printer emulation."; case IDS_2133: + return L"libgs is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."; + case IDS_2134: return L"libfluidsynth is required for FluidSynth MIDI output."; - case IDS_2129: + case IDS_2130: return L"Make sure libpcap is installed and that you are on a libpcap-compatible network connection."; - case IDS_2114: + case IDS_2115: return L"Unable to initialize Ghostscript"; case IDS_2063: return L"Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine."; case IDS_2064: return L"Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card."; - case IDS_2128: + case IDS_2129: return L"Hardware not available"; - case IDS_2142: + case IDS_2143: return L"Monitor in sleep mode"; } return L""; @@ -706,7 +706,7 @@ mouse_poll() mouse_y = mousedata.deltay; mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; + mouse_buttons = mousedata.mousebuttons; SDL_UnlockMutex(mousemutex); } diff --git a/src/unix/unix_cdrom.c b/src/unix/unix_cdrom.c index 0419c6018..bbeed0149 100644 --- a/src/unix/unix_cdrom.c +++ b/src/unix/unix_cdrom.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handle the platform-side of CDROM/ZIP/MO drives. + * Handle the platform-side of CDROM/ZIP/MO drives. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #include diff --git a/src/upi42.c b/src/upi42.c index eb0a46e1c..6937644ad 100644 --- a/src/upi42.c +++ b/src/upi42.c @@ -767,7 +767,7 @@ UPI42_COND_JMP_IMM(JNT1, !upi42->t1, ) UPI42_COND_JMP_IMM(JF0, upi42->psw & 0x20, ) UPI42_COND_JMP_IMM(JF1, upi42->sts & 0x08, ) UPI42_COND_JMP_IMM(JTF, !upi42->tf, upi42->tf = 0) -UPI42_COND_JMP_IMM(JBb, upi42->a &(1 << ((fetchdat >> 5) & 7)), ) +UPI42_COND_JMP_IMM(JBb, upi42->a & (1 << ((fetchdat >> 5) & 7)), ) UPI42_COND_JMP_IMM(JNIBF, !(upi42->sts & 0x02), ) UPI42_COND_JMP_IMM(JOBF, upi42->sts & 0x01, ) diff --git a/src/usb.c b/src/usb.c index 04b22064d..75e60d438 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Universal Serial Bus emulation (currently dummy UHCI and - * OHCI). + * Universal Serial Bus emulation (currently dummy UHCI and + * OHCI). * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020 Miran Grca. */ #include #include diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index fd88103c7..a5ea1059a 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c @@ -20,12 +20,12 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c vid_ati28800.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c - vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c - vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c - vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c - vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c - vid_sdac_ramdac.c vid_ogc.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c - vid_xga.c) + vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c + vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c + vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c + vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c + vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_nga.c + vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) if(MGA) target_compile_definitions(vid PRIVATE USE_MGA) diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 46663af51..c2aa2b6ad 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -22,6 +22,7 @@ #include #include #include +#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> @@ -215,7 +216,7 @@ typedef struct mach64_t { } accel; fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + atomic_int fifo_read_idx, fifo_write_idx; thread_t *fifo_thread; event_t *wake_fifo_thread; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index a49c89c18..8dba373df 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -120,7 +120,7 @@ cga_in(uint16_t addr, void *p) void cga_pravetz_out(uint16_t addr, uint8_t val, void *p) { - cga_t *cga = (cga_t *) p; + cga_t *cga = (cga_t *) p; cga->fontbase = (((unsigned int) val) << 8); } diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index 6dbb10d33..a343087d4 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -425,7 +425,7 @@ static const device_config_t colorplus_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t colorplus_device = { diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index ba18a0ba8..af1c06335 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -1305,7 +1305,7 @@ static const device_config_t ega_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t ega_device = { diff --git a/src/video/vid_et3000.c b/src/video/vid_et3000.c new file mode 100644 index 000000000..1d6288d9c --- /dev/null +++ b/src/video/vid_et3000.c @@ -0,0 +1,301 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Tseng Labs ET3000. + * + * Authors: Miran Grca, + * + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/mca.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> + +#define BIOS_ROM_PATH "roms/video/et3000/Tseng ET3000AX ISA VGA-VGA ULTRA.bin" + +typedef struct { + const char *name; + int type; + + svga_t svga; + + rom_t bios_rom; + + uint8_t banking; +} et3000_t; + +static video_timings_t timing_et3000_isa = { VIDEO_ISA, 3, 3, 6, 5, 5, 10 }; + +static uint8_t et3000_in(uint16_t addr, void *priv); +static void et3000_out(uint16_t addr, uint8_t val, void *priv); + +static uint8_t +et3000_in(uint16_t addr, void *priv) +{ + et3000_t *dev = (et3000_t *) priv; + svga_t *svga = &dev->svga; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3cd: /*Banking*/ + return dev->banking; + + case 0x3d4: + return svga->crtcreg; + + case 0x3d5: + return svga->crtc[svga->crtcreg]; + } + + return svga_in(addr, svga); +} + +static void +et3000_out(uint16_t addr, uint8_t val, void *priv) +{ + et3000_t *dev = (et3000_t *) priv; + svga_t *svga = &dev->svga; + uint8_t old; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3c0: + case 0x3c1: + if (svga->attrff && (svga->attraddr == 0x16)) { + svga->attrregs[0x16] = val; + svga->chain4 &= ~0x10; + if (svga->gdcreg[5] & 0x40) + svga->chain4 |= (svga->attrregs[0x16] & 0x10); + svga_recalctimings(svga); + } + break; + + case 0x3c5: + if (svga->seqaddr == 4) { + svga->seqregs[4] = val; + + svga->chain2_write = !(val & 4); + svga->chain4 = (svga->chain4 & ~8) | (val & 8); + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8); + return; + } + break; + + case 0x3cf: + if ((svga->gdcaddr & 15) == 5) { + svga->chain4 &= ~0x10; + if (val & 0x40) + svga->chain4 |= (svga->attrregs[0x16] & 0x10); + } + break; + + case 0x3cd: /*Banking*/ + dev->banking = val; + if (!(svga->crtc[0x23] & 0x80) && !(svga->gdcreg[6] & 0x08)) { + switch ((val >> 6) & 3) { + case 0: /*128K segments*/ + svga->write_bank = (val & 7) << 17; + svga->read_bank = ((val >> 3) & 7) << 17; + break; + case 1: /*64K segments*/ + svga->write_bank = (val & 7) << 16; + svga->read_bank = ((val >> 3) & 7) << 16; + break; + } + } + return; + + case 0x3d4: + svga->crtcreg = val & 0x3f; + return; + + case 0x3d5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + + if (old != val) { + if (svga->crtcreg < 0x0e || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + + svga_out(addr, val, svga); +} + +static void +et3000_recalctimings(svga_t *svga) +{ + svga->ma_latch |= (svga->crtc[0x23] & 2) << 15; + if (svga->crtc[0x25] & 1) + svga->vblankstart |= 0x400; + if (svga->crtc[0x25] & 2) + svga->vtotal |= 0x400; + if (svga->crtc[0x25] & 4) + svga->dispend |= 0x400; + if (svga->crtc[0x25] & 8) + svga->vsyncstart |= 0x400; + if (svga->crtc[0x25] & 0x10) + svga->split |= 0x400; + + svga->interlace = !!(svga->crtc[0x25] & 0x80); + + if (svga->attrregs[0x16] & 0x10) { + svga->ma_latch <<= (1 << 0); + svga->rowoffset <<= (1 << 0); + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + svga->render = svga_render_4bpp_highres; + svga->hdisp *= 2; + break; + case 0x20: + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: + svga->render = svga_render_8bpp_highres; + break; + } + } + + /* pclog("HDISP = %i, HTOTAL = %i, ROWOFFSET = %i, INTERLACE = %i\n", + svga->hdisp, svga->htotal, svga->rowoffset, svga->interlace); */ + + switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x24] << 1) & 4)) { + case 0: + case 1: + break; + case 3: + svga->clock = (cpuclock * (double) (1ull << 32)) / 40000000.0; + break; + case 5: + svga->clock = (cpuclock * (double) (1ull << 32)) / 65000000.0; + break; + default: + svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0; + break; + } +} + +static void * +et3000_init(const device_t *info) +{ + const char *fn; + et3000_t *dev; + + dev = (et3000_t *) malloc(sizeof(et3000_t)); + memset(dev, 0x00, sizeof(et3000_t)); + dev->name = info->name; + dev->type = info->local; + fn = BIOS_ROM_PATH; + + switch (dev->type) { + case 0: /* ISA ET3000AX */ + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et3000_isa); + svga_init(info, &dev->svga, dev, device_get_config_int("memory") << 10, + et3000_recalctimings, et3000_in, et3000_out, + NULL, NULL); + io_sethandler(0x03c0, 32, + et3000_in, NULL, NULL, et3000_out, NULL, NULL, dev); + break; + } + + rom_init(&dev->bios_rom, (char *) fn, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + dev->svga.bpp = 8; + dev->svga.miscout = 1; + + dev->svga.packed_chain4 = 1; + + return (dev); +} + +static void +et3000_close(void *priv) +{ + et3000_t *dev = (et3000_t *) priv; + + svga_close(&dev->svga); + + free(dev); +} + +static void +et3000_speed_changed(void *priv) +{ + et3000_t *dev = (et3000_t *) priv; + + svga_recalctimings(&dev->svga); +} + +static void +et3000_force_redraw(void *priv) +{ + et3000_t *dev = (et3000_t *) priv; + + dev->svga.fullchange = changeframecount; +} + +static int +et3000_available(void) +{ + return rom_present(BIOS_ROM_PATH); +} + +static const device_config_t et3000_config[] = { + { .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 512, + .selection = { + { .description = "256 KB", + .value = 256 }, + { .description = "512 KB", + .value = 512 }, + { .description = "1 MB", + .value = 1024 }, + { .description = "" } } }, + { .type = CONFIG_END } +}; + +const device_t et3000_isa_device = { + .name = "Tseng Labs ET3000AX (ISA)", + .internal_name = "et3000ax", + .flags = DEVICE_ISA, + .local = 0, + .init = et3000_init, + .close = et3000_close, + .reset = NULL, + { .available = et3000_available }, + .speed_changed = et3000_speed_changed, + .force_redraw = et3000_force_redraw, + .config = et3000_config +}; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 930468fbf..5d0691514 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -726,7 +726,7 @@ et4000_init(const device_t *info) et4000_kasan_recalctimings, et4000_in, et4000_out, NULL, NULL); io_sethandler(0x03c0, 32, - et4000_in, NULL, NULL, et4000_out, NULL, NULL, dev); + et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, dev); io_sethandler(0x0250, 8, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, dev); io_sethandler(0x0258, 2, @@ -822,7 +822,7 @@ static const device_config_t et4000_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t et4000_isa_device = { diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index aaa0dc223..eb604f4ea 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2791,7 +2791,7 @@ static const device_config_t et4000w32p_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t et4000w32_device = { diff --git a/src/video/vid_f82c425.c b/src/video/vid_f82c425.c index 0d1b9f1d7..3fea0c1bd 100644 --- a/src/video/vid_f82c425.c +++ b/src/video/vid_f82c425.c @@ -96,7 +96,7 @@ f82c425_display_set(uint8_t internal) } uint8_t -f82c425_display_get() +f82c425_display_get(void) { return (uint8_t) st_display_internal; } diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 57e9735bd..5c13e3415 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -783,7 +783,7 @@ genius_close(void *p) } static int -genius_available() +genius_available(void) { return rom_present(BIOS_ROM_PATH); } diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index d141ad0e8..401166f54 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -641,7 +641,7 @@ static const device_config_t hercules_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t hercules_device = { diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 692bcd42b..ea569cd3e 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -736,7 +736,7 @@ static const device_config_t herculesplus_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t herculesplus_device = { diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 734e4cc90..72d101e2b 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -1629,17 +1629,17 @@ ht216_force_redraw(void *p) } static const device_config_t v7_vga_1024i_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 512, .selection = { - { .description = "256 kB", + { .description = "256 kB", .value = 256 }, - { .description = "512 kB", + { .description = "512 kB", .value = 512 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; // clang-format off diff --git a/src/video/vid_im1024.c b/src/video/vid_im1024.c index 15aab0cb8..9e08ce583 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -1034,7 +1034,7 @@ im1024_close(void *priv) } static int -im1024_available() +im1024_available(void) { return rom_present(BIOS_ROM_PATH); } diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 3c88c5ccd..5ace70058 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -370,7 +370,7 @@ static const device_config_t mda_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mda_device = { diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 134b778b2..6da9a7c0f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -18,6 +18,7 @@ #include #include #include +#include #include <86box/86box.h> #include <86box/io.h> #include <86box/timer.h> @@ -429,7 +430,7 @@ typedef struct mystique_t { xzoomctrl, pixel_count, trap_count; - volatile int busy, blitter_submit_refcount, + atomic_int busy, blitter_submit_refcount, blitter_submit_dma_refcount, blitter_complete_refcount, endprdmasts_pending, softrap_pending, fifo_read_idx, fifo_write_idx; @@ -5577,7 +5578,7 @@ static const device_config_t mystique_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t millennium_device = { diff --git a/src/video/vid_nga.c b/src/video/vid_nga.c index 8b61cd83f..86173f198 100644 --- a/src/video/vid_nga.c +++ b/src/video/vid_nga.c @@ -677,7 +677,7 @@ const device_config_t nga_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t nga_device = { diff --git a/src/video/vid_ogc.c b/src/video/vid_ogc.c index f5e5c1911..eddc6da8d 100644 --- a/src/video/vid_ogc.c +++ b/src/video/vid_ogc.c @@ -535,7 +535,7 @@ ogc_speed_changed(void *priv) } void -ogc_mdaattr_rebuild() +ogc_mdaattr_rebuild(void) { int c; @@ -646,7 +646,7 @@ const device_config_t ogc_m24_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t ogc_m24_device = { diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 134947c06..3d82d459a 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -884,7 +884,7 @@ static const device_config_t paradise_wd90c30_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t paradise_wd90c30_device = { diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 089110d34..89d1505bb 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -2130,9 +2130,9 @@ pgc_ito_raster(pgc_t *dev, int32_t *x, int32_t *y) void pgc_recalctimings(pgc_t *dev) { - double disptime, _dispontime, _dispofftime; - double pixel_clock = (cpuclock / (dev->cga_selected ? 25175000.0 : dev->native_pixel_clock) * (double) (1ull << 32)); - uint8_t crtc0 = 97, crtc1 = 80; /* Values from MDA, taken from there due to the 25 MHz refresh rate. */ + double disptime, _dispontime, _dispofftime; + double pixel_clock = (cpuclock / (dev->cga_selected ? 25175000.0 : dev->native_pixel_clock) * (double) (1ull << 32)); + uint8_t crtc0 = 97, crtc1 = 80; /* Values from MDA, taken from there due to the 25 MHz refresh rate. */ /* Multiply pixel clock by 8. */ pixel_clock *= 8.0; diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index 66d87bb2e..10f97cf4f 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -380,7 +380,7 @@ static const device_config_t rtg_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t realtek_rtg3106_device = { diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index b31100596..6c93c32f4 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -22,6 +22,7 @@ #include #include #include +#include #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> @@ -272,33 +273,33 @@ typedef struct s3_t { } accel; struct { - uint32_t nop; - uint32_t cntl; - uint32_t stretch_filt_const; - uint32_t src_dst_step; - uint32_t crop; - uint32_t src_base, dest_base; - uint32_t src, dest; - uint32_t srcbase, dstbase; - int32_t dda_init_accumulator; - int32_t k1, k2; - int dm_index; - int dither_matrix_idx; - int src_step, dst_step; - int sx, sx_backup, sy; - double cx, dx; - double cy, dy; - int sx_scale_int, sx_scale_int_backup; - double sx_scale; - double sx_scale_dec; - double sx_scale_inc; - double sx_scale_backup; - double sx_scale_len; - int dither, host_data, scale_down; - int input; - int len, start; - int odf, idf, yuv; - volatile int busy; + uint32_t nop; + uint32_t cntl; + uint32_t stretch_filt_const; + uint32_t src_dst_step; + uint32_t crop; + uint32_t src_base, dest_base; + uint32_t src, dest; + uint32_t srcbase, dstbase; + int32_t dda_init_accumulator; + int32_t k1, k2; + int dm_index; + int dither_matrix_idx; + int src_step, dst_step; + int sx, sx_backup, sy; + double cx, dx; + double cy, dy; + int sx_scale_int, sx_scale_int_backup; + double sx_scale; + double sx_scale_dec; + double sx_scale_inc; + double sx_scale_backup; + double sx_scale_len; + int dither, host_data, scale_down; + int input; + int len, start; + int odf, idf, yuv; + atomic_int busy; } videoengine; struct @@ -334,7 +335,7 @@ typedef struct s3_t { } streams; fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + atomic_int fifo_read_idx, fifo_write_idx; uint8_t fifo_thread_run; @@ -351,10 +352,10 @@ typedef struct s3_t { uint32_t hwc_fg_col, hwc_bg_col; int hwc_col_stack_pos; - int translate; - int enable_8514; - int color_16bit; - volatile int busy, force_busy; + int translate; + int enable_8514; + int color_16bit; + atomic_int busy, force_busy; uint8_t thread_run, serialport; void *i2c, *ddc; @@ -875,12 +876,15 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; + + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } if (s3->accel.cmd & 0x1000) { s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); @@ -1413,12 +1417,15 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) s3->accel.short_stroke = val; s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; + + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } if (s3->accel.cmd & 0x1000) { s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); @@ -1686,8 +1693,15 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) } } else { if (addr & 0x8000) { - s3_accel_out_fifo(s3, addr & 0xffff, val); + if ((addr == 0xe2e8) || (addr == 0xe2e9)) { + if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) + goto mmio_byte_write; + else + s3_accel_out_fifo(s3, addr & 0xffff, val); + } else + s3_accel_out_fifo(s3, addr & 0xffff, val); } else { +mmio_byte_write: if (s3->accel.cmd & 0x100) { if ((s3->accel.cmd & 0x600) == 0x200) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -1739,8 +1753,8 @@ s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) if (addr == 0x811c) s3_accel_out_fifo_w(s3, 0x9ee8, val); else { - if (addr == 0xe2e8 || addr == 0xe2ea) { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) + if ((addr == 0xe2e8) || (addr == 0xe2ea)) { + if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || (s3->chip == S3_86C928) || (s3->chip == S3_86C928PCI)) s3_accel_out_pixtrans_w(s3, val); else { s3_accel_write_fifo(s3, addr, val); @@ -3141,8 +3155,12 @@ s3_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; if (s3->chip != S3_VISION868) { if (s3->chip == S3_86C928) { - if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600) - svga->hdisp <<= 1; + if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600) { + if ((s3->width != 1600) && (svga->dispend == 1024) && (svga->hdisp != 1280)) + svga->hdisp <<= 2; + else + svga->hdisp <<= 1; + } } else if ((s3->chip != S3_86C801) && (s3->chip != S3_86C805) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968)) { if (s3->width == 1280 || s3->width == 1600) svga->hdisp <<= 1; @@ -3553,9 +3571,8 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&s3->mmio_mapping, 0xb8000, 0x8000); else mem_mapping_set_addr(&s3->mmio_mapping, 0xa0000, 0x10000); - } else { - mem_mapping_enable(&s3->mmio_mapping); } + mem_mapping_enable(&s3->mmio_mapping); } else { mem_mapping_disable(&s3->mmio_mapping); } @@ -6213,12 +6230,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 1: /*Draw line*/ if (!cpu_input) { - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; + + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } s3->accel.sy = s3->accel.maj_axis_pcnt; @@ -6433,22 +6453,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.cx = s3->accel.cur_x; - s3->accel.cy = s3->accel.cur_y; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.cur_x_bit12) { - if (s3->accel.cx <= 0x7ff) { - s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; - } else { - s3->accel.cx |= ~0xfff; - } + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; } - if (s3->accel.cur_y_bit12) { - if (s3->accel.cy <= 0x7ff) { - s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; - } else { - s3->accel.cy |= ~0xfff; - } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; } s3->accel.dest = dstbase + s3->accel.cy * s3->width; @@ -6658,42 +6670,21 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) - s3->accel.dx |= ~0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) - s3->accel.dy |= ~0xfff; + s3->accel.dx = s3->accel.destx_distp & 0x7ff; + if (s3->accel.destx_distp & 0x800) + s3->accel.dx |= ~0x7ff; + s3->accel.dy = s3->accel.desty_axstp & 0x7ff; + if (s3->accel.desty_axstp & 0x800) + s3->accel.dy |= ~0x7ff; - s3->accel.cx = s3->accel.cur_x; - s3->accel.cy = s3->accel.cur_y; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.destx_distp >= 0xfffff000) { /* avoid overflow */ - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.cur_x_bit12) { - if (s3->accel.cx <= 0x7ff) { - s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; - } else { - s3->accel.cx |= ~0xfff; - } - } - if (s3->accel.cur_y_bitres > 0xfff) - s3->accel.cy = s3->accel.cur_y_bitres; - } else { - if (s3->accel.cur_x_bit12) { - if (s3->accel.cx <= 0x7ff) { /* overlap x */ - s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; - } else { /* x end is negative */ - s3->accel.cx |= ~0xfff; - } - } - if (s3->accel.cur_y_bit12) { - if (s3->accel.cy <= 0x7ff) { /* overlap y */ - s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; - } else { /* y end is negative */ - s3->accel.cy |= ~0xfff; - } - } + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; } s3->accel.src = srcbase + s3->accel.cy * s3->width; @@ -8579,83 +8570,83 @@ s3_force_redraw(void *p) } static const device_config_t s3_orchid_86c911_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 1, .selection = { - { .description = "512 KB", + { .description = "512 KB", .value = 0 }, - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; static const device_config_t s3_9fx_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 2, .selection = { - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "2 MB", + { .description = "2 MB", .value = 2 }, - /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ - { + /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ + { .description = "" } } }, - { .type = CONFIG_END} + { .type = CONFIG_END } }; static const device_config_t s3_phoenix_trio32_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 2, .selection = { - { .description = "512 KB", + { .description = "512 KB", .value = 0 }, - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "2 MB", + { .description = "2 MB", .value = 2 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; static const device_config_t s3_standard_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 4, .selection = { - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "2 MB", + { .description = "2 MB", .value = 2 }, - { .description = "4 MB", + { .description = "4 MB", .value = 4 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; static const device_config_t s3_968_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 4, .selection = { - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "2 MB", + { .description = "2 MB", .value = 2 }, - { .description = "4 MB", + { .description = "4 MB", .value = 4 }, - { .description = "8 MB", + { .description = "8 MB", .value = 8 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; const device_t s3_orchid_86c911_isa_device = { diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index d8a440f30..99661d309 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -22,6 +22,7 @@ #include #include #include +#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/io.h> @@ -237,10 +238,9 @@ typedef struct virge_t { s3d_t s3d_tri; - s3d_t s3d_buffer[RB_SIZE]; - int s3d_read_idx, s3d_write_idx; - int s3d_busy; - int render_idx; + s3d_t s3d_buffer[RB_SIZE]; + atomic_int s3d_read_idx, s3d_write_idx; + atomic_int s3d_busy; struct { @@ -4587,7 +4587,7 @@ static const device_config_t s3_trio3d2x_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t s3_virge_325_pci_device = { diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 5984d9bb0..d8fa55ce3 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -946,7 +946,7 @@ device_config_t sigma_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t sigma_device = { diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index e542ddd91..21d0b50ee 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -20,11 +20,13 @@ * Copyright 2016-2019 Miran Grca. */ #include +#include #include #include -#include #include +#include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" #include <86box/device.h> @@ -54,9 +56,26 @@ uint8_t svga_rotate[8][256]; static svga_t *svga_pri; int vga_on, ibm8514_on; -svga_t - * - svga_get_pri() +#ifdef ENABLE_SVGA_LOG +int svga_do_log = ENABLE_SVGA_LOG; + +static void +svga_log(const char *fmt, ...) +{ + va_list ap; + + if (svga_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define svga_log(fmt, ...) +#endif + +svga_t * +svga_get_pri(void) { return svga_pri; } @@ -235,7 +254,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) break; case 6: if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - switch (val & 0xC) { + switch (val & 0xc) { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; @@ -363,7 +382,9 @@ svga_in(uint16_t addr, void *p) svga->cgastat &= ~0x30; else svga->cgastat ^= 0x30; + ret = svga->cgastat; + break; } @@ -453,7 +474,7 @@ svga_recalctimings(svga_t *svga) svga->render = svga_render_blank; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) /*40 column*/ { + if (svga->seqregs[1] & 8) { /*40 column*/ svga->render = svga_render_text_40; svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; /* Character clock is off by 1 now in 40-line modes, on all cards. */ @@ -590,7 +611,7 @@ svga_recalctimings(svga_t *svga) if (svga->dpms) { if (!svga->dpms_ui) { svga->dpms_ui = 1; - ui_sb_set_text_w(plat_get_string(IDS_2142)); + ui_sb_set_text_w(plat_get_string(IDS_2143)); } } else if (svga->dpms_ui) { svga->dpms_ui = 0; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 31c857cf5..ab2eb5c96 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -73,9 +73,9 @@ static const device_t vid_internal_device = { .config = NULL }; -// clang-format off static const VIDEO_CARD video_cards[] = { + // clang-format off { &vid_none_device }, { &vid_internal_device }, { &atiega_device }, @@ -143,6 +143,7 @@ video_cards[] = { { &nec_sv9000_device }, { &et4000k_isa_device }, { &et2000_device }, + { &et3000_isa_device }, { &et4000_isa_device }, { &et4000w32_device }, { &et4000w32i_isa_device }, @@ -207,6 +208,7 @@ video_cards[] = { { &tgui9680_pci_device }, { &voodoo_banshee_device }, { &creative_voodoo_banshee_device }, + { &voodoo_3_1000_device }, { &voodoo_3_2000_device }, { &voodoo_3_3000_device }, { &mach64gx_vlb_device }, @@ -249,11 +251,18 @@ video_cards[] = { { &s3_diamond_stealth_4000_agp_device }, { &s3_trio3d2x_agp_device }, { &velocity_100_agp_device }, + { &velocity_200_agp_device }, + { &voodoo_3_1000_agp_device }, { &voodoo_3_2000_agp_device }, { &voodoo_3_3000_agp_device }, + { &voodoo_3_3500_agp_ntsc_device }, + { &voodoo_3_3500_agp_pal_device }, + { &compaq_voodoo_3_3500_agp_device }, + { &voodoo_3_3500_se_agp_device }, + { &voodoo_3_3500_si_agp_device }, { NULL } + // clang-format on }; -// clang-format on #ifdef ENABLE_VID_TABLE_LOG int vid_table_do_log = ENABLE_VID_TABLE_LOG; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index af7ffb3de..dd39daf8e 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -427,32 +427,18 @@ tgui_out(uint16_t addr, uint8_t val, void *p) val = (svga->crtc[7] & ~0x10) | (val & 0x10); old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; - - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - } switch (svga->crtcreg) { case 0x1e: svga->vram_display_mask = (val & 0x80) ? tgui->vram_mask : 0x3ffff; break; case 0x21: - if (old != val) { - if (!tgui->pci) { - tgui->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20; - tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; - svga->decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; - } - tgui_recalcmapping(tgui); + if (!tgui->pci) { + tgui->linear_base = ((val & 0xc0) << 18) | ((val & 0x0f) << 20); + tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; + svga->decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; } + tgui_recalcmapping(tgui); break; case 0x34: @@ -484,9 +470,12 @@ tgui_out(uint16_t addr, uint8_t val, void *p) if (tgui->type >= TGUI_9440) { svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; - if (tgui->type >= TGUI_9660 && (tgui->accel.ger22 & 0xff) == 8) { - svga->hwcursor.x <<= 1; + + if ((tgui->accel.ger22 & 0xff) == 8) { + if (svga->bpp != 24) + svga->hwcursor.x <<= 1; } + svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x0f) << 18) | (svga->hwcursor.yoff * 8); @@ -500,6 +489,18 @@ tgui_out(uint16_t addr, uint8_t val, void *p) } break; } + + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } return; case 0x3D8: @@ -623,7 +624,9 @@ tgui_in(uint16_t addr, void *p) void tgui_recalctimings(svga_t *svga) { - tgui_t *tgui = (tgui_t *) svga->p; + tgui_t *tgui = (tgui_t *) svga->p; + uint8_t ger22lower = tgui->accel.ger22 & 0xff; + uint8_t ger22upper = (tgui->accel.ger22 >> 8); if (!svga->rowoffset) svga->rowoffset = 0x100; @@ -631,11 +634,12 @@ tgui_recalctimings(svga_t *svga) if (svga->crtc[0x29] & 0x10) svga->rowoffset |= 0x100; - if (tgui->type >= TGUI_9440 && svga->bpp >= 24) { - if ((tgui->accel.bpp == 0) && (tgui->accel.ger22 & 0xff) != 14 && (svga->bpp == 24)) + if ((tgui->type >= TGUI_9440) && (svga->bpp >= 24)) { + if ((tgui->accel.bpp == 0) && (ger22lower != 14) && (svga->bpp == 24)) svga->hdisp = (svga->crtc[1] + 1) * 8; - if (tgui->accel.bpp == 3 && (tgui->accel.ger22 & 0xff) == 14 && (svga->bpp == 32) && (tgui->type == TGUI_9440)) + if ((tgui->accel.bpp == 3) && (ger22lower == 14) && (svga->bpp == 32) && (tgui->type == TGUI_9440)) svga->rowoffset <<= 1; + // pclog("Accelbpp = %d, ger22lower = %02x, ger22upper = %02x, bpp = %d, rowoffset = %d.\n", tgui->accel.bpp, ger22lower, ger22upper, svga->bpp, svga->rowoffset); } if ((svga->crtc[0x1e] & 0xA0) == 0xA0) @@ -669,7 +673,7 @@ tgui_recalctimings(svga_t *svga) svga->lowres = !(svga->crtc[0x2a] & 0x40); svga->interlace = !!(svga->crtc[0x1e] & 4); - if (svga->interlace && tgui->type < TGUI_9440) + if (svga->interlace && (tgui->type < TGUI_9440)) svga->rowoffset >>= 1; if (tgui->type >= TGUI_9440) { @@ -737,10 +741,21 @@ tgui_recalctimings(svga_t *svga) case 8: svga->render = svga_render_8bpp_highres; if (tgui->type >= TGUI_9660) { - if (svga->dispend == 512) + if ((svga->dispend == 510) || (svga->dispend == 512)) svga->hdisp = 1280; - else if (svga->dispend == 600 && svga->hdisp == 800 && svga->vtotal == 651) + else if ((svga->dispend == 600) && (svga->hdisp == 800) && svga->interlace) svga->hdisp = 1600; + + switch (svga->hdisp) { + case 640: + if (ger22upper & 0x01) + svga->rowoffset = 0x50; + break; + case 1600: + if (svga->rowoffset != 0x100) + svga->rowoffset = 0x100; + break; + } } break; case 15: @@ -818,7 +833,6 @@ tgui_recalcmapping(tgui_t *tgui) mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); else if ((svga->crtc[0x36] & 0x03) == 0x03) mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); - mem_mapping_disable(&svga->mapping); } else { switch (svga->gdcreg[6] & 0xC) { case 0x0: /*128k at A0000*/ @@ -925,7 +939,7 @@ tgui_pci_read(int func, int addr, void *p) return 0x10; case 0x02: - return (tgui->type == TGUI_9440) ? 0x40 : 0x60; /*TGUI9440AGi or TGUI9660XGi*/ + return (tgui->type == TGUI_9440) ? 0x40 : 0x60; /*TGUI9440AGi or TGUI96x0XGi*/ case 0x03: return (tgui->type == TGUI_9440) ? 0x94 : 0x96; @@ -1330,12 +1344,14 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) int x, y; int c, d; uint32_t out; - uint32_t src_dat = 0, dst_dat, pat_dat; - int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; - int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; - uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; - uint16_t *vram_w = (uint16_t *) svga->vram; - uint32_t *vram_l = (uint32_t *) svga->vram; + uint32_t src_dat = 0, dst_dat, pat_dat; + int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; + int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; + uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint32_t *vram_l = (uint32_t *) svga->vram; + uint8_t ger22lower = tgui->accel.ger22 & 0xff; + uint8_t ger22upper = (tgui->accel.ger22 >> 8) & 0xff; if (tgui->accel.bpp == 0) { trans_col &= 0xff; @@ -1391,80 +1407,40 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } - /*Other than mode stuff, this bit is undocumented*/ - switch (tgui->accel.ger22 & 0xff) { - case 0: - switch (tgui->accel.ger22 >> 8) { - case 0x41: - tgui->accel.pitch = 640; - break; - } + switch (svga->hdisp) { + case 640: + case 1024: + case 1280: + tgui->accel.pitch = svga->hdisp; break; + case 800: /*Disassembly of the TGUI9440/96x0 drivers shows that 800x600 is treated as 832 in the acceleration pitch (0x340 as horizontal display)*/ + tgui->accel.pitch = svga->hdisp + 32; + break; + case 1600: + tgui->accel.pitch = 2048; + break; + } - case 4: - switch (tgui->accel.ger22 >> 8) { - case 0: + switch (ger22lower) { + case 4: /*8-bit mode for modes up to 1024x768.*/ + case 9: /*15-bit and 16-bit modes.*/ + if (!(ger22upper & 0x01)) { + if (ger22upper == 0x00) tgui->accel.pitch = 1024; - break; - case 0x40: - tgui->accel.pitch = 640; - break; - case 0x50: - tgui->accel.pitch = 832; - break; } break; - case 8: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = 2048; - break; - case 0x60: - tgui->accel.pitch = 1280; - break; - } - break; - case 9: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = svga->hdisp; - if (tgui->type == TGUI_9440) - tgui->accel.pitch = 1024; - break; - case 0x40: - tgui->accel.pitch = 640; - break; - case 0x50: - tgui->accel.pitch = 832; - break; - } - break; - case 13: - switch (tgui->accel.ger22 >> 8) { - case 0x60: - tgui->accel.pitch = 2048; - if (tgui->type >= TGUI_9660) { - if (svga->hdisp == 1280) - tgui->accel.pitch = svga->hdisp; - } - break; - } - break; - case 14: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = 1024; - break; - case 0x40: - tgui->accel.pitch = 640; - break; - case 0x50: - tgui->accel.pitch = 832; - break; + case 8: /*8-bit mode for modes greater than 1024x768 and 24-bit mode for 640x480 (latter is TGUI9440AGi only).*/ + if (!(ger22upper & 0x01)) { + if (ger22upper == 0x00) { + if (svga->bpp == 24) + tgui->accel.pitch = 2048; + } } break; } + // pclog("TGUI accel command = %x, ger22 = %04x, hdisp = %d, dispend = %d, vtotal = %d, rowoffset = %d, svgabpp = %d, interlace = %d, accelbpp = %d, pitch = %d.\n", tgui->accel.command, tgui->accel.ger22, svga->hdisp, svga->dispend, svga->vtotal, svga->rowoffset, svga->bpp, svga->interlace, tgui->accel.bpp, tgui->accel.pitch); + switch (tgui->accel.command) { case TGUI_BITBLT: if (count == -1) { @@ -1730,32 +1706,14 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) break; case TGUI_BRESENHAMLINE: - { - int steep = 1; - int16_t dminor, dmajor, destxtmp, tmpswap; - int16_t cx, cy, dx, dy, err; + if (count == -1) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy = tgui->accel.dst_y & 0xfff; -#define SWAP(a, b) \ - tmpswap = a; \ - a = b; \ - b = tmpswap; - - dminor = tgui->accel.src_y; - if (tgui->accel.src_y & 0x1000) - dminor |= ~0xfff; - dminor >>= 1; - - destxtmp = tgui->accel.src_x; - if (tgui->accel.src_x & 0x1000) - destxtmp |= ~0xfff; - - dmajor = -(destxtmp - (dminor << 1)) >> 1; - - cx = dmajor; - cy = dminor; - - dx = tgui->accel.dst_x & 0xfff; - dy = tgui->accel.dst_y & 0xfff; + if (tgui->accel.dst_x & 0x1000) + tgui->accel.dx |= ~0xfff; + if (tgui->accel.dst_y & 0x1000) + tgui->accel.dy |= ~0xfff; tgui->accel.left = tgui->accel.src_x_clip & 0xfff; tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; @@ -1769,74 +1727,113 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.left >>= 2; tgui->accel.right >>= 2; } + } - err = tgui->accel.size_x + tgui->accel.src_y; - if ((tgui->accel.size_x + tgui->accel.src_y) & 0x1000) - err |= ~0xfff; + // pclog("TGUI bres = %04x, err = %d, sizex = %d, sizey = %d, srcx = %d, srcy = %d.\n", tgui->accel.flags & 0x700, err, tgui->accel.size_x, tgui->accel.size_y, cx, tgui->accel.src_y); + while (count-- && (tgui->accel.y <= (tgui->accel.size_y))) { + // READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - if (tgui->accel.flags & 0x400) { - steep = 0; - SWAP(dx, dy); - SWAP(xdir, ydir); + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat); + + pat_dat = tgui->accel.fg_col; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + MIX(); + + WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out); } - while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) { + break; + } - /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if (steep) { - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.pitch), dst_dat); - - pat_dat = tgui->accel.fg_col; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - MIX(); - - WRITE(dx + (dy * tgui->accel.pitch), out); - } - } else { - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dy >= tgui->accel.left && dy <= tgui->accel.right && dx >= tgui->accel.top && dx <= tgui->accel.bottom)) { - READ(dy + (dx * tgui->accel.pitch), dst_dat); - - pat_dat = tgui->accel.fg_col; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - MIX(); - - WRITE(dy + (dx * tgui->accel.pitch), out); - } + if (tgui->accel.err >= (tgui->accel.size_y & 0xfff)) { + // pclog("Bres DEC: destx = %d, desty = %d, err = %d, sizey = %d.\n", tgui->accel.src_x, tgui->accel.src_y, tgui->accel.err, tgui->accel.size_y); + if ((tgui->accel.src_x >= 2048) && (tgui->accel.src_x < 4096)) + tgui->accel.err -= (4096 - tgui->accel.src_x); + else if ((tgui->accel.src_x >= 4096) && (tgui->accel.src_x < 32768)) + tgui->accel.err -= (32768 - tgui->accel.src_x); + else + tgui->accel.err += tgui->accel.src_x; + /*Step minor axis*/ + switch (tgui->accel.flags & 0x700) { + case 0x300: + tgui->accel.dy--; + break; + case 0x100: + tgui->accel.dy--; + break; + case 0x700: + tgui->accel.dx--; + break; + case 0x500: + tgui->accel.dx++; + break; + case 0x200: + tgui->accel.dy++; + break; + case 0x000: + tgui->accel.dy++; + break; + case 0x600: + tgui->accel.dx--; + break; + case 0x400: + tgui->accel.dx++; + break; } + } else { + // pclog("Bres INC: desty = %d, destx = %d, err = %d, sizey = %d.\n", tgui->accel.src_y, tgui->accel.src_x, tgui->accel.err, tgui->accel.size_y); + tgui->accel.err += tgui->accel.src_y; + } - if (tgui->accel.y == tgui->accel.size_y) + /*Step major axis*/ + switch (tgui->accel.flags & 0x700) { + case 0x300: + tgui->accel.dx--; + break; + case 0x100: + tgui->accel.dx++; + break; + case 0x700: + tgui->accel.dy--; + break; + case 0x500: + tgui->accel.dy--; + break; + case 0x200: + tgui->accel.dx--; + break; + case 0x000: + tgui->accel.dx++; + break; + case 0x600: + tgui->accel.dy++; + break; + case 0x400: + tgui->accel.dy++; break; - - while (err > 0) { - dy += ydir; - err -= (cx << 1); - } - dx += xdir; - err += (cy << 1); - - tgui->accel.y++; } + + tgui->accel.y++; } break; case TGUI_SHORTVECTOR: - { - int16_t dx, dy; + if (count == -1) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy = tgui->accel.dst_y & 0xfff; - dx = tgui->accel.dst_x & 0xfff; - dy = tgui->accel.dst_y & 0xfff; + if (tgui->accel.dst_x & 0x1000) + tgui->accel.dx |= ~0xfff; + if (tgui->accel.dst_y & 0x1000) + tgui->accel.dy |= ~0xfff; tgui->accel.left = tgui->accel.src_x_clip & 0xfff; tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; @@ -1850,74 +1847,77 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.left >>= 2; tgui->accel.right >>= 2; } + } - while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + while (count-- && (tgui->accel.y <= (tgui->accel.sv_size_y & 0xfff))) { + // READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.pitch), dst_dat); + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat); - pat_dat = tgui->accel.fg_col; + pat_dat = tgui->accel.fg_col; - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; - MIX(); + MIX(); - WRITE(dx + (dy * tgui->accel.pitch), out); - } - - if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff)) - break; - - switch ((tgui->accel.sv_size_y >> 8) & 0xe0) { - case 0x00: - dx++; - break; - case 0x20: - dx++; - dy--; - break; - case 0x40: - dy--; - break; - case 0x60: - dx--; - dy--; - break; - case 0x80: - dx--; - break; - case 0xa0: - dx--; - dy++; - break; - case 0xc0: - dy++; - break; - case 0xe0: - dx++; - dy++; - break; - } - - tgui->accel.y++; + WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out); } + + if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff)) + break; + + switch ((tgui->accel.sv_size_y >> 8) & 0xe0) { + case 0x00: + tgui->accel.dx++; + break; + case 0x20: + tgui->accel.dx++; + tgui->accel.dy--; + break; + case 0x40: + tgui->accel.dy--; + break; + case 0x60: + tgui->accel.dx--; + tgui->accel.dy--; + break; + case 0x80: + tgui->accel.dx--; + break; + case 0xa0: + tgui->accel.dx--; + tgui->accel.dy++; + break; + case 0xc0: + tgui->accel.dy++; + break; + case 0xe0: + tgui->accel.dx++; + tgui->accel.dy++; + break; + } + + tgui->accel.y++; } break; case TGUI_FASTLINE: - { - if (tgui->type < TGUI_9660) - break; + if (tgui->type < TGUI_9660) + break; - int16_t dx, dy; + if (count == -1) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy = tgui->accel.dst_y & 0xfff; - dx = tgui->accel.dst_x & 0xfff; - dy = tgui->accel.dst_y & 0xfff; + if (tgui->accel.dst_x & 0x1000) + tgui->accel.dx |= ~0xfff; + if (tgui->accel.dst_y & 0x1000) + tgui->accel.dy |= ~0xfff; tgui->accel.left = tgui->accel.src_x_clip & 0xfff; tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; @@ -1931,62 +1931,62 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.left >>= 2; tgui->accel.right >>= 2; } + } - while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + while (count-- && (tgui->accel.y <= (tgui->accel.size_y & 0xfff))) { + // READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.pitch), dst_dat); + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if (tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom) { + READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat); - pat_dat = tgui->accel.fg_col; + pat_dat = tgui->accel.fg_col; - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; - MIX(); + MIX(); - WRITE(dx + (dy * tgui->accel.pitch), out); - } - - if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) - break; - - switch ((tgui->accel.size_y >> 8) & 0xe0) { - case 0x00: - dx++; - break; - case 0x20: - dx++; - dy--; - break; - case 0x40: - dy--; - break; - case 0x60: - dx--; - dy--; - break; - case 0x80: - dx--; - break; - case 0xa0: - dx--; - dy++; - break; - case 0xc0: - dy++; - break; - case 0xe0: - dx++; - dy++; - break; - } - - tgui->accel.y++; + WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out); } + + if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) + break; + + switch ((tgui->accel.size_y >> 8) & 0xe0) { + case 0x00: + tgui->accel.dx++; + break; + case 0x20: + tgui->accel.dx++; + tgui->accel.dy--; + break; + case 0x40: + tgui->accel.dy--; + break; + case 0x60: + tgui->accel.dx--; + tgui->accel.dy--; + break; + case 0x80: + tgui->accel.dx--; + break; + case 0xa0: + tgui->accel.dx--; + tgui->accel.dy++; + break; + case 0xc0: + tgui->accel.dy++; + break; + case 0xe0: + tgui->accel.dx++; + tgui->accel.dy++; + break; + } + + tgui->accel.y++; } break; } @@ -2007,7 +2007,14 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) break; case 9: - tgui->accel.bpp = 1; + switch (tgui->svga.bpp) { + case 32: + tgui->accel.bpp = 3; + break; + default: + tgui->accel.bpp = 1; + break; + } break; case 13: @@ -2129,6 +2136,11 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) break; case 0x2141: /*Size X*/ tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); + tgui->accel.err = tgui->accel.size_x; + if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096)) + tgui->accel.err -= 4096; + else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768)) + tgui->accel.err -= 32768; break; case 0x2142: /*Size Y*/ tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; @@ -2365,7 +2377,6 @@ tgui_accel_in(uint16_t addr, void *p) case 0x2122: return tgui->accel.ger22 & 0xff; - case 0x2123: return tgui->accel.ger22 >> 8; @@ -2646,7 +2657,14 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) break; case 9: - tgui->accel.bpp = 1; + switch (tgui->svga.bpp) { + case 32: + tgui->accel.bpp = 3; + break; + default: + tgui->accel.bpp = 1; + break; + } break; case 13: @@ -2768,6 +2786,11 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) break; case 0x41: /*Size X*/ tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); + tgui->accel.err = tgui->accel.size_x; + if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096)) + tgui->accel.err -= 4096; + else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768)) + tgui->accel.err -= 32768; break; case 0x42: /*Size Y*/ tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; @@ -3020,7 +3043,6 @@ tgui_accel_read(uint32_t addr, void *p) case 0x22: return tgui->accel.ger22 & 0xff; - case 0x23: return tgui->accel.ger22 >> 8; diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 96931ac6f..ed249f618 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -31,9 +31,9 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define TVGA8900B_ID 0x03 -#define TVGA9000B_ID 0x23 -#define TVGA8900CLD_ID 0x33 +#define TVGA8900B_ID 0x03 +#define TVGA9000B_ID 0x23 +#define TVGA8900CLD_ID 0x33 #define ROM_TVGA_8900B "roms/video/tvga/tvga8900b.vbi" #define ROM_TVGA_8900CLD "roms/video/tvga/trident.bin" diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 2d61c47f1..326ff9879 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -876,7 +876,7 @@ voodoo_force_blit(void *p) } void * -voodoo_card_init() +voodoo_card_init(void) { int c; voodoo_t *voodoo = malloc(sizeof(voodoo_t)); @@ -1152,7 +1152,7 @@ voodoo_2d3d_card_init(int type) } void * -voodoo_init() +voodoo_init(const device_t *info) { voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); uint32_t tmuConfig = 1; @@ -1390,7 +1390,7 @@ static const device_config_t voodoo_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t voodoo_device = { diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index cb4d2b18e..4170dd345 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -46,6 +46,19 @@ #include <86box/vid_voodoo_regs.h> #include <86box/vid_voodoo_render.h> +#define ROM_BANSHEE "roms/video/voodoo/Pci_sg.rom" +#define ROM_CREATIVE_BANSHEE "roms/video/voodoo/BlasterPCI.rom" +#define ROM_VOODOO3_1000 "roms/video/voodoo/1k11sg.rom" +#define ROM_VOODOO3_2000 "roms/video/voodoo/2k11sd.rom" +#define ROM_VOODOO3_3000 "roms/video/voodoo/3k12sd.rom" +#define ROM_VOODOO3_3500_AGP_NTSC "roms/video/voodoo/35k05n.rom" +#define ROM_VOODOO3_3500_AGP_PAL "roms/video/voodoo/35k05p.rom" +#define ROM_VOODOO3_3500_AGP_COMPAQ "roms/video/voodoo/V3_3500_AGP_SD_2.15.05_Compaq.rom" +#define ROM_VOODOO3_3500_SE_AGP "roms/video/voodoo/V3_3500_AGP_SD_2.15.06_NTSC_Falcon_Northwest.rom" +#define ROM_VOODOO3_3500_SI_AGP "roms/video/voodoo/V3_3500_AGP_SD_2.15.07_PAL_3500TV-SI.rom" +#define ROM_VELOCITY_100 "roms/video/voodoo/Velocity100.VBI" +#define ROM_VELOCITY_200 "roms/video/voodoo/Velocity200sg.rom" + static video_timings_t timing_banshee = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; static video_timings_t timing_banshee_agp = { .type = VIDEO_AGP, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; @@ -61,9 +74,14 @@ static uint8_t vb_filter_bx_g[256][256]; enum { TYPE_BANSHEE = 0, + TYPE_V3_1000, TYPE_V3_2000, TYPE_V3_3000, - TYPE_VELOCITY100 + TYPE_V3_3500, + TYPE_V3_3500_COMPAQ, + TYPE_V3_3500_SI, + TYPE_VELOCITY100, + TYPE_VELOCITY200 }; typedef struct banshee_t { @@ -171,22 +189,22 @@ enum { }; enum { - cmdBaseAddr0 = 0x20, - cmdBaseSize0 = 0x24, - cmdBump0 = 0x28, - cmdRdPtrL0 = 0x2c, - cmdRdPtrH0 = 0x30, - cmdAMin0 = 0x34, - cmdAMax0 = 0x3c, - cmdStatus0 = 0x40, - cmdFifoDepth0 = 0x44, - cmdHoleCnt0 = 0x48, + cmdBaseAddr0 = 0x20, + cmdBaseSize0 = 0x24, + cmdBump0 = 0x28, + cmdRdPtrL0 = 0x2c, + cmdRdPtrH0 = 0x30, + cmdAMin0 = 0x34, + cmdAMax0 = 0x3c, + cmdStatus0 = 0x40, + cmdFifoDepth0 = 0x44, + cmdHoleCnt0 = 0x48, - Agp_agpReqSize = 0x00, - Agp_agpHostAddressLow = 0x04, - Agp_agpHostAddressHigh = 0x08, - Agp_agpGraphicsAddress = 0x0C, - Agp_agpGraphicsStride = 0x10, + Agp_agpReqSize = 0x00, + Agp_agpHostAddressLow = 0x04, + Agp_agpHostAddressHigh = 0x08, + Agp_agpGraphicsAddress = 0x0C, + Agp_agpGraphicsStride = 0x10, }; #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) @@ -1175,6 +1193,10 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr) ret = voodoo->cmd_status; break; + case cmdBaseSize0: + ret = voodoo->cmdfifo_size; + break; + case 0x108: break; @@ -1386,7 +1408,7 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) // banshee_log("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val); switch (addr & 0x1fc) { case Agp_agpHostAddressLow: - banshee->agpHostAddressLow = val; + banshee->agpHostAddressLow = val; break; case Agp_agpHostAddressHigh: @@ -3010,6 +3032,13 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int } break; + case TYPE_V3_1000: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x52; + banshee->pci_regs[0x2f] = 0x00; + break; + case TYPE_V3_2000: banshee->pci_regs[0x2c] = 0x1a; banshee->pci_regs[0x2d] = 0x12; @@ -3024,12 +3053,40 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->pci_regs[0x2f] = 0x00; break; + case TYPE_V3_3500: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x60; + banshee->pci_regs[0x2f] = 0x00; + break; + + case TYPE_V3_3500_COMPAQ: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x4f; + banshee->pci_regs[0x2f] = 0x12; + break; + + case TYPE_V3_3500_SI: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x61; + banshee->pci_regs[0x2f] = 0x00; + break; + case TYPE_VELOCITY100: banshee->pci_regs[0x2c] = 0x1a; banshee->pci_regs[0x2d] = 0x12; banshee->pci_regs[0x2e] = 0x4b; banshee->pci_regs[0x2f] = 0x00; break; + + case TYPE_VELOCITY200: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x54; + banshee->pci_regs[0x2f] = 0x00; + break; } video_inform(VIDEO_FLAG_TYPE_SPECIAL, banshee->agp ? &timing_banshee_agp : &timing_banshee); @@ -3040,70 +3097,172 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int static void * banshee_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/Pci_sg.rom", 1, TYPE_BANSHEE, VOODOO_BANSHEE, 0); + return banshee_init_common(info, ROM_BANSHEE, 1, TYPE_BANSHEE, VOODOO_BANSHEE, 0); } + static void * creative_banshee_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/BlasterPCI.rom", 0, TYPE_BANSHEE, VOODOO_BANSHEE, 0); + return banshee_init_common(info, ROM_CREATIVE_BANSHEE, 0, TYPE_BANSHEE, VOODOO_BANSHEE, 0); } + +static void * +v3_1000_init(const device_t *info) +{ + return banshee_init_common(info, ROM_VOODOO3_1000, 1, TYPE_V3_1000, VOODOO_3, 0); +} + +static void * +v3_1000_agp_init(const device_t *info) +{ + return banshee_init_common(info, ROM_VOODOO3_1000, 1, TYPE_V3_1000, VOODOO_3, 1); +} + static void * v3_2000_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3, 0); + return banshee_init_common(info, ROM_VOODOO3_2000, 0, TYPE_V3_2000, VOODOO_3, 0); } + static void * v3_2000_agp_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3, 1); + return banshee_init_common(info, ROM_VOODOO3_2000, 0, TYPE_V3_2000, VOODOO_3, 1); } + static void * v3_2000_agp_onboard_init(const device_t *info) { return banshee_init_common(info, NULL, 1, TYPE_V3_2000, VOODOO_3, 1); } + static void * v3_3000_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3, 0); + return banshee_init_common(info, ROM_VOODOO3_3000, 0, TYPE_V3_3000, VOODOO_3, 0); } + static void * v3_3000_agp_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3, 1); + return banshee_init_common(info, ROM_VOODOO3_3000, 0, TYPE_V3_3000, VOODOO_3, 1); } + +static void * +v3_3500_agp_ntsc_init(const device_t *info) +{ + return banshee_init_common(info, ROM_VOODOO3_3500_AGP_NTSC, 0, TYPE_V3_3500, VOODOO_3, 1); +} + +static void * +v3_3500_agp_pal_init(const device_t *info) +{ + return banshee_init_common(info, ROM_VOODOO3_3500_AGP_PAL, 0, TYPE_V3_3500, VOODOO_3, 1); +} + +static void * +compaq_v3_3500_agp_init(const device_t *info) +{ + return banshee_init_common(info, ROM_VOODOO3_3500_AGP_COMPAQ, 0, TYPE_V3_3500_COMPAQ, VOODOO_3, 1); +} + +static void * +v3_3500_se_agp_init(const device_t *info) +{ + return banshee_init_common(info, ROM_VOODOO3_3500_SE_AGP, 0, TYPE_V3_3500, VOODOO_3, 1); +} + +static void * +v3_3500_si_agp_init(const device_t *info) +{ + return banshee_init_common(info, ROM_VOODOO3_3500_SI_AGP, 0, TYPE_V3_3500_SI, VOODOO_3, 1); +} + static void * velocity_100_agp_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/Velocity100.VBI", 1, TYPE_VELOCITY100, VOODOO_3, 1); + return banshee_init_common(info, ROM_VELOCITY_100, 1, TYPE_VELOCITY100, VOODOO_3, 1); +} + +static void * +velocity_200_agp_init(const device_t *info) +{ + return banshee_init_common(info, ROM_VELOCITY_200, 1, TYPE_VELOCITY200, VOODOO_3, 1); } static int banshee_available(void) { - return rom_present("roms/video/voodoo/Pci_sg.rom"); + return rom_present(ROM_BANSHEE); } + static int creative_banshee_available(void) { - return rom_present("roms/video/voodoo/BlasterPCI.rom"); + return rom_present(ROM_CREATIVE_BANSHEE); } + +static int +v3_1000_available(void) +{ + return rom_present(ROM_VOODOO3_1000); +} +#define v3_1000_agp_available v3_1000_available + static int v3_2000_available(void) { - return rom_present("roms/video/voodoo/2k11sd.rom"); + return rom_present(ROM_VOODOO3_2000); } #define v3_2000_agp_available v3_2000_available + static int v3_3000_available(void) { - return rom_present("roms/video/voodoo/3k12sd.rom"); + return rom_present(ROM_VOODOO3_3000); } #define v3_3000_agp_available v3_3000_available + +static int +v3_3500_agp_ntsc_available(void) +{ + return rom_present(ROM_VOODOO3_3500_AGP_NTSC); +} + +static int +v3_3500_agp_pal_available(void) +{ + return rom_present(ROM_VOODOO3_3500_AGP_PAL); +} + +static int +compaq_v3_3500_agp_available(void) +{ + return rom_present(ROM_VOODOO3_3500_AGP_COMPAQ); +} + +static int +v3_3500_se_agp_available(void) +{ + return rom_present(ROM_VOODOO3_3500_SE_AGP); +} + +static int +v3_3500_si_agp_available(void) +{ + return rom_present(ROM_VOODOO3_3500_SI_AGP); +} + static int velocity_100_available(void) { - return rom_present("roms/video/voodoo/Velocity100.VBI"); + return rom_present(ROM_VELOCITY_100); +} + +static int +velocity_200_available(void) +{ + return rom_present(ROM_VELOCITY_200); } static void @@ -3164,6 +3323,34 @@ const device_t creative_voodoo_banshee_device = { banshee_sdram_config }; +const device_t voodoo_3_1000_device = { + .name = "3dfx Voodoo3 1000", + .internal_name = "voodoo3_1k_pci", + .flags = DEVICE_PCI, + .local = 0, + .init = v3_1000_init, + .close = banshee_close, + .reset = NULL, + { .available = v3_1000_available }, + .speed_changed = banshee_speed_changed, + .force_redraw = banshee_force_redraw, + banshee_sgram_config +}; + +const device_t voodoo_3_1000_agp_device = { + .name = "3dfx Voodoo3 1000", + .internal_name = "voodoo3_1k_agp", + .flags = DEVICE_AGP, + .local = 0, + .init = v3_1000_agp_init, + .close = banshee_close, + .reset = NULL, + { .available = v3_1000_agp_available }, + .speed_changed = banshee_speed_changed, + .force_redraw = banshee_force_redraw, + banshee_sgram_config +}; + const device_t voodoo_3_2000_device = { .name = "3dfx Voodoo3 2000", .internal_name = "voodoo3_2k_pci", @@ -3234,6 +3421,76 @@ const device_t voodoo_3_3000_agp_device = { banshee_sdram_config }; +const device_t voodoo_3_3500_agp_ntsc_device = { + .name = "3dfx Voodoo3 3500 TV (NTSC)", + .internal_name = "voodoo3_3500_agp_ntsc", + .flags = DEVICE_AGP, + .local = 0, + .init = v3_3500_agp_ntsc_init, + .close = banshee_close, + .reset = NULL, + { .available = v3_3500_agp_ntsc_available }, + .speed_changed = banshee_speed_changed, + .force_redraw = banshee_force_redraw, + banshee_sdram_config +}; + +const device_t voodoo_3_3500_agp_pal_device = { + .name = "3dfx Voodoo3 3500 TV (PAL)", + .internal_name = "voodoo3_3500_agp_pal", + .flags = DEVICE_AGP, + .local = 0, + .init = v3_3500_agp_pal_init, + .close = banshee_close, + .reset = NULL, + { .available = v3_3500_agp_pal_available }, + .speed_changed = banshee_speed_changed, + .force_redraw = banshee_force_redraw, + banshee_sdram_config +}; + +const device_t compaq_voodoo_3_3500_agp_device = { + .name = "Compaq Voodoo3 3500 TV", + .internal_name = "compaq_voodoo3_3500_agp", + .flags = DEVICE_AGP, + .local = 0, + .init = compaq_v3_3500_agp_init, + .close = banshee_close, + .reset = NULL, + { .available = compaq_v3_3500_agp_available }, + .speed_changed = banshee_speed_changed, + .force_redraw = banshee_force_redraw, + banshee_sdram_config +}; + +const device_t voodoo_3_3500_se_agp_device = { + .name = "Falcon Northwest Voodoo3 3500 SE", + .internal_name = "voodoo3_3500_se_agp", + .flags = DEVICE_AGP, + .local = 0, + .init = v3_3500_se_agp_init, + .close = banshee_close, + .reset = NULL, + { .available = v3_3500_se_agp_available }, + .speed_changed = banshee_speed_changed, + .force_redraw = banshee_force_redraw, + banshee_sdram_config +}; + +const device_t voodoo_3_3500_si_agp_device = { + .name = "3dfx Voodoo3 3500 SI", + .internal_name = "voodoo3_3500_si_agp", + .flags = DEVICE_AGP, + .local = 0, + .init = v3_3500_si_agp_init, + .close = banshee_close, + .reset = NULL, + { .available = v3_3500_si_agp_available }, + .speed_changed = banshee_speed_changed, + .force_redraw = banshee_force_redraw, + banshee_sdram_config +}; + const device_t velocity_100_agp_device = { .name = "3dfx Velocity 100", .internal_name = "velocity100_agp", @@ -3247,3 +3504,17 @@ const device_t velocity_100_agp_device = { .force_redraw = banshee_force_redraw, banshee_sdram_config }; + +const device_t velocity_200_agp_device = { + .name = "3dfx Velocity 200", + .internal_name = "velocity200_agp", + .flags = DEVICE_AGP, + .local = 0, + .init = velocity_200_agp_init, + .close = banshee_close, + .reset = NULL, + { .available = velocity_200_available }, + .speed_changed = banshee_speed_changed, + .force_redraw = banshee_force_redraw, + banshee_sgram_config +}; diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index 8a9b24337..98f439d79 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -1,6 +1,6 @@ /*Current issues : - missing screen->screen scaled blits with format conversion - - missing YUV blits + - missing YUV blits (YUV -> 32-bit, 24-bit, or 16-bit RGB now done) - missing linestyle - missing wait for vsync - missing reversible lines @@ -109,7 +109,7 @@ bansheeblt_log(const char *fmt, ...) } } #else -# define banshee_log(fmt, ...) +# define bansheeblt_log(fmt, ...) #endif static int @@ -303,6 +303,7 @@ update_src_stride(voodoo_t *voodoo) bpp = 24; break; case SRC_FORMAT_COL_32_BPP: + case SRC_FORMAT_COL_YUYV: bpp = 32; break; @@ -399,6 +400,88 @@ banshee_do_rectfill(voodoo_t *voodoo) end_command(voodoo); } +void +DECODE_YUYV422(uint32_t *buf, uint8_t *src) +{ + do { + int wp = 0; + + uint8_t y1, y2; + int8_t Cr, Cb; + int dR, dG, dB; + int r, g, b; + + y1 = src[0]; + Cr = src[1] - 0x80; + y2 = src[2]; + Cb = src[3] - 0x80; + + dR = (359 * Cr) >> 8; + dG = (88 * Cb + 183 * Cr) >> 8; + dB = (453 * Cb) >> 8; + + r = y1 + dR; + r = CLAMP(r); + g = y1 - dG; + g = CLAMP(g); + b = y1 + dB; + b = CLAMP(b); + buf[wp++] = r | (g << 8) | (b << 16); + + r = y2 + dR; + r = CLAMP(r); + g = y2 - dG; + g = CLAMP(g); + b = y2 + dB; + b = CLAMP(b); + buf[wp++] = r | (g << 8) | (b << 16); + } while (0); +} + +void +DECODE_YUYV422_16BPP(uint16_t *buf, uint8_t *src) +{ + do { + int wp = 0; + + uint8_t y1, y2; + int8_t Cr, Cb; + int dR, dG, dB; + int r, g, b; + + y1 = src[0]; + Cr = src[1] - 0x80; + y2 = src[2]; + Cb = src[3] - 0x80; + + dR = (359 * Cr) >> 8; + dG = (88 * Cb + 183 * Cr) >> 8; + dB = (453 * Cb) >> 8; + + r = y1 + dR; + r = CLAMP(r); + r >>= 3; + g = y1 - dG; + g = CLAMP(g); + g >>= 2; + b = y1 + dB; + b = CLAMP(b); + b >>= 3; + buf[wp++] = r | (g << 5) | (b << 11); + + r = y2 + dR; + r = CLAMP(r); + r >>= 3; + g = y2 - dG; + g = CLAMP(g); + g >>= 2; + b = y2 + dB; + b = CLAMP(b); + b >>= 3; + buf[wp++] = r | (g << 5) | (b << 11); + } while (0); +} + static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled) { @@ -513,8 +596,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128 * 32); if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { - uint32_t src_data = 0; - int transparent = 0; + uint32_t src_data = 0; + uint32_t src_data_yuv = 0; /* Used in YUYV-to-RGB convesions. */ + int transparent = 0; switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { case SRC_FORMAT_COL_1_BPP: @@ -554,6 +638,11 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr src_data = *(uint32_t *) &src_p[src_x_real]; break; } + case SRC_FORMAT_COL_YUYV: + { + src_data_yuv = *(uint32_t *) &src_p[src_x_real]; + break; + } default: fatal("banshee_do_screen_to_screen_blt: unknown srcFormat %08x\n", voodoo->banshee_blt.srcFormat); @@ -567,9 +656,54 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr src_data = (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); } - if (!transparent) - PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, src_data, src_colorkey); + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_YUYV) { + if (((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_24_BPP) || + ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_32_BPP)) { + uint32_t rgbcol[2] = { 0, 0 }; + DECODE_YUYV422(rgbcol, (uint8_t *) &src_data_yuv); + + bansheeblt_log("YUV -> 24 bpp or 32 bpp\n"); + + if (!transparent) { + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, rgbcol[0], src_colorkey); + } + + if (use_x_dir) { + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } else { + dst_x++; + } + + if (!transparent) { + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, rgbcol[1], src_colorkey); + } + } else if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP) { + uint32_t rgbcol = 0; + DECODE_YUYV422_16BPP((uint16_t *) &rgbcol, (uint8_t *) &src_data_yuv); + + bansheeblt_log("YUV -> 16 bpp\n"); + + if (!transparent) { + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, rgbcol & 0xffff, src_colorkey); + } + + if (use_x_dir) { + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } else { + dst_x++; + } + + if (!transparent) { + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, rgbcol >> 16, src_colorkey); + } + } else + fatal("banshee_do_screen_to_screen_blt: unknown dstFormat %08x\n", voodoo->banshee_blt.dstFormat); + } else { + if (!transparent) + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, src_data, src_colorkey); + } } + if (use_x_dir) { src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; @@ -1183,6 +1317,7 @@ voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) voodoo->banshee_blt.src_bpp = 24; break; case SRC_FORMAT_COL_32_BPP: + case SRC_FORMAT_COL_YUYV: voodoo->banshee_blt.src_bpp = 32; break; case SRC_FORMAT_COL_16_BPP: diff --git a/src/video/vid_voodoo_fifo.c b/src/video/vid_voodoo_fifo.c index 8dd8fb594..d90c12bb5 100644 --- a/src/video/vid_voodoo_fifo.c +++ b/src/video/vid_voodoo_fifo.c @@ -359,8 +359,8 @@ voodoo_fifo_thread(void *param) break; case 2: - if (voodoo->type < VOODOO_BANSHEE) - fatal("CMDFIFO2: Not Banshee\n"); + if (voodoo->type < VOODOO_2) + fatal("CMDFIFO2: Not Voodoo 2\n"); mask = (header >> 3); addr = 8; while (mask) { @@ -429,6 +429,8 @@ voodoo_fifo_thread(void *param) if (v_num == 3 && ((header >> 3) & 7) == 0) v_num = 0; } + while (num--) + cmdfifo_get(voodoo); break; case 4: diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index 1b8e13022..3d5580d04 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -72,8 +72,8 @@ voodoo_reg_log(const char *fmt, ...) void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *) p; - void (*voodoo_recalc_tex)(voodoo_t *voodoo, int tmu) = NULL; + voodoo_t *voodoo = (voodoo_t *) p; + void (*voodoo_recalc_tex)(voodoo_t * voodoo, int tmu) = NULL; union { uint32_t i; float f; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index cbec48739..84c1805ff 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * IBM XGA emulation. + * IBM XGA emulation. * * * - * Authors: TheCollector1995. + * Authors: TheCollector1995. * - * Copyright 2022 TheCollector1995. + * Copyright 2022 TheCollector1995. */ #include #include @@ -2663,7 +2663,6 @@ static void svga_t *svga = svga_get_pri(); xga_t *xga = &svga->xga; FILE *f; - uint32_t temp; uint32_t initial_bios_addr = device_get_config_hex20("init_bios_addr"); uint8_t *rom = NULL; @@ -2683,13 +2682,11 @@ static void f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); (void) fseek(f, 0L, SEEK_END); - temp = ftell(f); (void) fseek(f, 0L, SEEK_SET); rom = malloc(xga->bios_rom.sz); memset(rom, 0xff, xga->bios_rom.sz); (void) !fread(rom, xga->bios_rom.sz, 1, f); - temp -= xga->bios_rom.sz; (void) fclose(f); xga->bios_rom.rom = rom; @@ -2816,7 +2813,7 @@ static const device_config_t xga_configuration[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t xga_device = { diff --git a/src/video/video.c b/src/video/video.c index 9fed77bf2..18f2e1427 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -544,7 +544,7 @@ video_process_8_monitor(int x, int y, int monitor_index) if (monitors[monitor_index].target_buffer->line[y][xx] <= 0xff) monitors[monitor_index].target_buffer->line[y][xx] = monitors[monitor_index].mon_pal_lookup[monitors[monitor_index].target_buffer->line[y][xx]]; else - monitors[monitor_index].target_buffer->line[y][xx] = 0x00000000; + monitors[monitor_index].target_buffer->line[y][xx] = 0x00000000; } } @@ -1076,12 +1076,11 @@ loadfont_common(FILE *f, int format) (void) !fread(&fontdat12x18[c][0], 1, 36, f); break; - case 10: /* Pravetz */ + case 10: /* Pravetz */ for (c = 0; c < 1024; c++) /* Allow up to 1024 chars */ for (d = 0; d < 8; d++) fontdat[c][d] = fgetc(f) & 0xff; break; - } (void) fclose(f); diff --git a/src/vnc.c b/src/vnc.c index e7b112be2..3bffdcd9d 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implement the VNC remote renderer with LibVNCServer. + * Implement the VNC remote renderer with LibVNCServer. * * * - * Authors: Fred N. van Kempen, - * Based on raw code by RichardG, + * Authors: Fred N. van Kempen, + * Based on raw code by RichardG, * - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include @@ -192,12 +192,12 @@ vnc_init(UNUSED(void *arg)) rfbPixelFormat rpf = { /* * Screen format: - * 32bpp; 32 depth; - * little endian; - * true color; - * max 255 R/G/B; - * red shift 16; green shift 8; blue shift 0; - * padding + * 32bpp; 32 depth; + * little endian; + * true color; + * max 255 R/G/B; + * red shift 16; green shift 8; blue shift 0; + * padding */ 32, 32, 0, 1, 255, 255, 255, 16, 8, 0, 0, 0 }; diff --git a/src/vnc_keymap.c b/src/vnc_keymap.c index a3c60d398..923f6ecf0 100644 --- a/src/vnc_keymap.c +++ b/src/vnc_keymap.c @@ -1,33 +1,33 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Define the XKBD to ScanCode translation tables for VNC. + * Define the XKBD to ScanCode translation tables for VNC. * - * VNC uses the XKBD key code definitions to transport keystroke - * information, so we just need some tables to translate those - * into PC-ready scan codes. + * VNC uses the XKBD key code definitions to transport keystroke + * information, so we just need some tables to translate those + * into PC-ready scan codes. * - * We only support XKBD pages 0 (Latin-1) and 255 (special keys) - * in these tables, other pages (languages) not [yet] supported. + * We only support XKBD pages 0 (Latin-1) and 255 (special keys) + * in these tables, other pages (languages) not [yet] supported. * - * The tables define up to two keystrokes.. the upper byte is - * the first keystroke, and the lower byte the second. If value - * is 0x00, the keystroke is not sent. + * The tables define up to two keystrokes.. the upper byte is + * the first keystroke, and the lower byte the second. If value + * is 0x00, the keystroke is not sent. * - * NOTE: The values are as defined in the Microsoft document named - * "Keyboard Scan Code Specification", version 1.3a of 2000/03/16. + * NOTE: The values are as defined in the Microsoft document named + * "Keyboard Scan Code Specification", version 1.3a of 2000/03/16. * * * - * Authors: Fred N. van Kempen, - * Based on raw code by RichardG, + * Authors: Fred N. van Kempen, + * Based on raw code by RichardG, * - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include diff --git a/src/win/86Box-qt.rc b/src/win/86Box-qt.rc index 0d4d8158f..3a92439d8 100644 --- a/src/win/86Box-qt.rc +++ b/src/win/86Box-qt.rc @@ -1,20 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Application resource script for Windows. + * Application resource script for Windows. * - * Authors: Miran Grca, - * Fred N. van Kempen, - * David Hrdlička, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 David Hrdlička. - * Copyright 2021 Laci bá' + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * David Hrdlička, + * + * Copyright 2016-2019 Miran Grca. + * Copyright 2018-2019 David Hrdlička. + * Copyright 2021 Laci bá' */ #define IN_RESOURCE_H #include <86box/version.h> diff --git a/src/win/86Box.manifest b/src/win/86Box.manifest index 58f2d4194..4a2941845 100644 --- a/src/win/86Box.manifest +++ b/src/win/86Box.manifest @@ -34,7 +34,7 @@ - + diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 342870d62..e180873ff 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -1,20 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Application resource script for Windows. + * Application resource script for Windows. * - * Authors: Miran Grca, - * Fred N. van Kempen, - * David Hrdlička, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 David Hrdlička. - * Copyright 2021 Laci bá' + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * David Hrdlička, + * + * Copyright 2016-2019 Miran Grca. + * Copyright 2018-2019 David Hrdlička. + * Copyright 2021 Laci bá' */ #define IN_RESOURCE_H #include <86box/resource.h> @@ -360,3 +362,4 @@ END #include "languages/es-ES.rc" #include "languages/tr-TR.rc" #include "languages/uk-UA.rc" +#include "languages/zh-TW.rc" diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 7452f82dc..34e6dde9b 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # enable_language(RC) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 3718cd952..61ed25f9b 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -1,56 +1,56 @@ # # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# Makefile for Win32 (MinGW32) environment. +# Makefile for Win32 (MinGW32) environment. # -# Authors: Miran Grca, -# Fred N. van Kempen, +# Authors: Miran Grca, +# Fred N. van Kempen, # # Various compile-time options. ifndef STUFF -STUFF := + STUFF := endif # Add feature selections here. ifndef EXTRAS -EXTRAS := + EXTRAS := endif ifndef DEV_BUILD -DEV_BUILD := n + DEV_BUILD := n endif ifeq ($(DEV_BUILD), y) ifndef DEBUG - DEBUG := y + DEBUG := y endif ifndef GDBSTUB - GDBSTUB := n + GDBSTUB := n endif ifndef DEV_BRANCH - DEV_BRANCH := y + DEV_BRANCH := y endif ifndef AMD_K5 - AMD_K5 := y + AMD_K5 := y endif ifndef AN430TX - AN430TX := y + AN430TX := y endif ifndef CYRIX_6X86 - CYRIX_6X86 := y + CYRIX_6X86 := y endif ifndef DESKPRO386 - DESKPRO386 := y + DESKPRO386 := y endif ifndef GUSMAX - GUSMAX := y + GUSMAX := y endif ifndef ISAMEM_RAMPAGE ISAMEM_RAMPAGE := y @@ -62,56 +62,56 @@ ifeq ($(DEV_BUILD), y) ISAMEM_BRAT := y endif ifndef LASERXT - LASERXT := y + LASERXT := y endif ifndef MGA - MGA := y + MGA := y endif ifndef OLIVETTI - OLIVETTI := y + OLIVETTI := y endif ifndef OPEN_AT - OPEN_AT := y + OPEN_AT := y endif ifndef PAS16 - PAS16 := y + PAS16 := y endif ifndef SIO_DETECT - SIO_DETECT := y + SIO_DETECT := y endif ifndef VGAWONDER - VGAWONDER := y + VGAWONDER := y endif ifndef XL24 - XL24 := y + XL24 := y endif ifndef NEW_KBC - NEW_KBC := n + NEW_KBC := n endif else ifndef DEBUG - DEBUG := n + DEBUG := n endif ifndef GDBSTUB - GDBSTUB := n + GDBSTUB := n endif ifndef DEV_BRANCH - DEV_BRANCH := n + DEV_BRANCH := n endif ifndef AMD_K5 - AMD_K5 := n + AMD_K5 := n endif ifndef AN430TX - AN430TX := n + AN430TX := n endif ifndef CYRIX_6X86 - CYRIX_6X86 := n + CYRIX_6X86 := n endif ifndef DESKPRO386 - DESKPRO386 := n + DESKPRO386 := n endif ifndef GUSMAX - GUSMAX := n + GUSMAX := n endif ifndef ISAMEM_RAMPAGE ISAMEM_RAMPAGE := n @@ -123,92 +123,92 @@ else ISAMEM_BRAT := n endif ifndef LASERXT - LASERXT := n + LASERXT := n endif ifndef MGA - MGA := n + MGA := n endif ifndef OLIVETTI - OLIVETTI := n + OLIVETTI := n endif ifndef OPEN_AT - OPEN_AT := n + OPEN_AT := n endif ifndef PAS16 - PAS16 := n + PAS16 := n endif ifndef SIO_DETECT - SIO_DETECT := n + SIO_DETECT := n endif ifndef VGAWONDER - VGAWONDER := n + VGAWONDER := n endif ifndef XL24 - XL24 := n + XL24 := n endif ifndef NEW_KBC - NEW_KBC := n + NEW_KBC := n endif endif # Defaults for several build options (possibly defined in a chained file.) ifndef AUTODEP -AUTODEP := n + AUTODEP := n endif ifndef OPTIM -OPTIM := n + OPTIM := n endif ifndef RELEASE -RELEASE := n + RELEASE := n endif ifndef X64 -X64 := n + X64 := n endif ifndef ARM -ARM := n + ARM := n endif ifndef ARM64 -ARM64 := n + ARM64 := n endif ifndef DINPUT - DINPUT := n + DINPUT := n endif ifndef FAUDIO - FAUDIO := n + FAUDIO := n endif ifndef OPENAL - OPENAL := n + OPENAL := y endif ifndef FLUIDSYNTH - FLUIDSYNTH := y + FLUIDSYNTH := y endif ifndef MUNT - MUNT := y + MUNT := y endif ifndef VNC - VNC := n + VNC := n endif ifndef NEW_DYNAREC - NEW_DYNAREC := n + NEW_DYNAREC := n endif ifndef DYNAREC - DYNAREC := y + DYNAREC := y endif ifndef CPPTHREADS - CPPTHREADS := y + CPPTHREADS := y endif ifndef RTMIDI - RTMIDI := y + RTMIDI := y endif ifeq ($(DYNAREC), y) ifeq ($(ARM), y) ifeq ($(NEW_DYNAREC), n) - DYNAREC := n + DYNAREC := n endif endif ifeq ($(ARM64), y) ifeq ($(NEW_DYNAREC), n) - DYNAREC := n + DYNAREC := n endif endif endif @@ -216,629 +216,626 @@ endif # Path to the dynamic recompiler code. ifeq ($(NEW_DYNAREC), y) - CODEGEN := codegen_new + CODEGEN := codegen_new else - CODEGEN := codegen + CODEGEN := codegen endif # Name of the executable. -PROG := 86Box +PROG := 86Box ######################################################################### -# Nothing should need changing from here on.. # +# Nothing should need changing from here on.. # ######################################################################### -VPATH := $(EXPATH) . $(CODEGEN) minitrace cpu \ - cdrom chipset device disk disk/minivhd floppy \ - game machine mem printer \ - sio sound \ - sound/munt sound/munt/c_interface sound/munt/sha1 \ - sound/munt/srchelper sound/munt/srchelper/srctools/src \ - sound/resid-fp sound/ymfm \ - scsi video network network/slirp win +VPATH := $(EXPATH) . $(CODEGEN) minitrace cpu \ + cdrom chipset device disk disk/minivhd floppy \ + game machine mem printer \ + sio sound \ + sound/munt sound/munt/c_interface sound/munt/sha1 \ + sound/munt/srchelper sound/munt/srchelper/srctools/src \ + sound/resid-fp sound/ymfm \ + scsi video network network/slirp win ifeq ($(X64), y) -TOOL_PREFIX := x86_64-w64-mingw32- + TOOL_PREFIX := x86_64-w64-mingw32- else -TOOL_PREFIX := i686-w64-mingw32- + TOOL_PREFIX := i686-w64-mingw32- endif -WINDRES := windres -STRIP := strip +WINDRES := windres +STRIP := strip ifeq ($(ARM64), y) -WINDRES := aarch64-w64-mingw32-windres -STRIP := aarch64-w64-mingw32-strip + WINDRES := aarch64-w64-mingw32-windres + STRIP := aarch64-w64-mingw32-strip endif ifeq ($(ARM), y) -WINDRES := armv7-w64-mingw32-windres -STRIP := armv7-w64-mingw32-strip + WINDRES := armv7-w64-mingw32-windres + STRIP := armv7-w64-mingw32-strip endif ifeq ($(CLANG), y) -CPP := clang++ -CC := clang -ifeq ($(ARM64), y) -CPP := aarch64-w64-mingw32-clang++ -CC := aarch64-w64-mingw32-clang -endif -ifeq ($(ARM), y) -CPP := armv7-w64-mingw32-clang++ -CC := armv7-w64-mingw32-clang -endif + CPP := clang++ + CC := clang + ifeq ($(ARM64), y) + CPP := aarch64-w64-mingw32-clang++ + CC := aarch64-w64-mingw32-clang + endif + ifeq ($(ARM), y) + CPP := armv7-w64-mingw32-clang++ + CC := armv7-w64-mingw32-clang + endif else -CPP := ${TOOL_PREFIX}g++ -CC := ${TOOL_PREFIX}gcc -ifeq ($(ARM64), y) -CPP := aarch64-w64-mingw32-g++ -CC := aarch64-w64-mingw32-gcc + CPP := ${TOOL_PREFIX}g++ + CC := ${TOOL_PREFIX}gcc + ifeq ($(ARM64), y) + CPP := aarch64-w64-mingw32-g++ + CC := aarch64-w64-mingw32-gcc + endif + ifeq ($(ARM), y) + CPP := armv7-w64-mingw32-g++ + CC := armv7-w64-mingw32-gcc + endif endif -ifeq ($(ARM), y) -CPP := armv7-w64-mingw32-g++ -CC := armv7-w64-mingw32-gcc -endif -endif -DEPS = -MMD -MF $*.d -c $< -DEPFILE := win/.depends +DEPS = -MMD -MF $*.d -c $< +DEPFILE := win/.depends # Set up the correct toolchain flags. -OPTS := $(EXTRAS) $(STUFF) -OPTS += -Iinclude -Iinclude_make \ - -iquote $(CODEGEN) -iquote cpu +OPTS := $(EXTRAS) $(STUFF) +OPTS += -Iinclude -Iinclude_make \ + -iquote $(CODEGEN) -iquote cpu ifdef EXFLAGS -OPTS += $(EXFLAGS) + OPTS += $(EXFLAGS) endif ifdef EXINC -OPTS += -I$(EXINC) + OPTS += -I$(EXINC) endif ifeq ($(OPTIM), y) - DFLAGS := -march=native + DFLAGS := -march=native else ifeq ($(X64), y) - DFLAGS := + DFLAGS := else - DFLAGS := -march=i686 + DFLAGS := -march=i686 endif endif ifeq ($(DEBUG), y) - DFLAGS += -ggdb -DDEBUG - AOPTIM := + DFLAGS += -ggdb -DDEBUG + AOPTIM := ifndef COPTIM - COPTIM := -Og + COPTIM := -Og endif else - DFLAGS += -g0 + DFLAGS += -g0 ifeq ($(OPTIM), y) - AOPTIM := -mtune=native + AOPTIM := -mtune=native ifndef COPTIM - COPTIM := -O3 -ffp-contract=fast -flto + COPTIM := -O3 -ffp-contract=fast -flto endif else ifndef COPTIM - COPTIM := -O3 + COPTIM := -O3 endif endif endif -AFLAGS := -msse2 -mfpmath=sse +AFLAGS := -msse2 -mfpmath=sse ifeq ($(ARM), y) - DFLAGS := -march=armv7-a - AOPTIM := - AFLAGS := -mfloat-abi=hard + DFLAGS := -march=armv7-a + AOPTIM := + AFLAGS := -mfloat-abi=hard endif ifeq ($(ARM64), y) - DFLAGS := -march=armv8-a - AOPTIM := - AFLAGS := -mfloat-abi=hard + DFLAGS := -march=armv8-a + AOPTIM := + AFLAGS := -mfloat-abi=hard endif -RFLAGS := --input-format=rc -O coff -Iinclude -Iinclude_make +RFLAGS := --input-format=rc -O coff -Iinclude -Iinclude_make ifeq ($(RELEASE), y) -OPTS += -DRELEASE_BUILD -RFLAGS += -DRELEASE_BUILD + OPTS += -DRELEASE_BUILD + RFLAGS += -DRELEASE_BUILD endif # Optional modules. ifeq ($(DYNAREC), y) -OPTS += -DUSE_DYNAREC -RFLAGS += -DUSE_DYNAREC + OPTS += -DUSE_DYNAREC + RFLAGS += -DUSE_DYNAREC ifeq ($(NEW_DYNAREC), y) - OPTS += -DUSE_NEW_DYNAREC - RFLAGS += -DUSE_NEW_DYNAREC + OPTS += -DUSE_NEW_DYNAREC + RFLAGS += -DUSE_NEW_DYNAREC ifeq ($(X64), y) - PLATCG := codegen_backend_x86-64.o codegen_backend_x86-64_ops.o codegen_backend_x86-64_ops_sse.o \ - codegen_backend_x86-64_uops.o + PLATCG := codegen_backend_x86-64.o codegen_backend_x86-64_ops.o codegen_backend_x86-64_ops_sse.o \ + codegen_backend_x86-64_uops.o else ifeq ($(ARM64), y) - PLATCG := codegen_backend_arm64.o codegen_backend_arm64_ops.o codegen_backend_arm64_uops.o \ - codegen_backend_arm64_imm.o + PLATCG := codegen_backend_arm64.o codegen_backend_arm64_ops.o codegen_backend_arm64_uops.o \ + codegen_backend_arm64_imm.o else ifeq ($(ARM), y) - PLATCG := codegen_backend_arm.o codegen_backend_arm_ops.o codegen_backend_arm_uops.o + PLATCG := codegen_backend_arm.o codegen_backend_arm_ops.o codegen_backend_arm_uops.o else - PLATCG := codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o \ - codegen_backend_x86_ops_sse.o codegen_backend_x86_uops.o + PLATCG := codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o \ + codegen_backend_x86_ops_sse.o codegen_backend_x86_uops.o endif - DYNARECOBJ := codegen.o codegen_accumulate.o codegen_allocator.o codegen_block.o codegen_ir.o codegen_ops.o \ - codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ - codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_helpers.o \ - codegen_ops_jump.o codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ - codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ - codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o $(PLATCG) + DYNARECOBJ := codegen.o codegen_accumulate.o codegen_allocator.o codegen_block.o codegen_ir.o codegen_ops.o \ + codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ + codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_helpers.o \ + codegen_ops_jump.o codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ + codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ + codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o $(PLATCG) else ifeq ($(X64), y) - PLATCG := codegen_x86-64.o codegen_accumulate_x86-64.o + PLATCG := codegen_x86-64.o codegen_accumulate_x86-64.o else - PLATCG := codegen_x86.o codegen_accumulate_x86.o + PLATCG := codegen_x86.o codegen_accumulate_x86.o endif - DYNARECOBJ := codegen.o \ - codegen_ops.o $(PLATCG) + DYNARECOBJ := codegen.o \ + codegen_ops.o $(PLATCG) endif - CGTOBJ := codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ - codegen_timing_p6.o codegen_timing_winchip.o codegen_timing_winchip2.o + CGTOBJ := codegen_timing_486.o \ + codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ + codegen_timing_p6.o codegen_timing_winchip.o codegen_timing_winchip2.o else ifeq ($(NEW_DYNAREC), y) - OPTS += -DUSE_NEW_DYNAREC - RFLAGS += -DUSE_NEW_DYNAREC + OPTS += -DUSE_NEW_DYNAREC + RFLAGS += -DUSE_NEW_DYNAREC endif endif ifeq ($(FLUIDSYNTH), y) -OPTS += -DUSE_FLUIDSYNTH -FSYNTHOBJ := midi_fluidsynth.o + OPTS += -DUSE_FLUIDSYNTH + FSYNTHOBJ := midi_fluidsynth.o endif ifeq ($(MUNT), y) -OPTS += -DUSE_MUNT -MUNTOBJ := midi_mt32.o \ - Analog.o BReverbModel.o Display.o File.o FileStream.o LA32Ramp.o \ - LA32FloatWaveGenerator.o LA32WaveGenerator.o \ - MidiStreamParser.o Part.o Partial.o PartialManager.o \ - Poly.o ROMInfo.o SampleRateConverter.o \ - FIRResampler.o IIR2xResampler.o LinearResampler.o ResamplerModel.o \ - SincResampler.o InternalResampler.o \ - Synth.o Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o + OPTS += -DUSE_MUNT + MUNTOBJ := midi_mt32.o \ + Analog.o BReverbModel.o Display.o File.o FileStream.o LA32Ramp.o \ + LA32FloatWaveGenerator.o LA32WaveGenerator.o \ + MidiStreamParser.o Part.o Partial.o PartialManager.o \ + Poly.o ROMInfo.o SampleRateConverter.o \ + FIRResampler.o IIR2xResampler.o LinearResampler.o ResamplerModel.o \ + SincResampler.o InternalResampler.o \ + Synth.o Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o endif ifeq ($(CPPTHREADS), y) -THREADOBJ := thread.o + THREADOBJ := thread.o else -THREADOBJ := win_thread.o + THREADOBJ := win_thread.o endif ifeq ($(VNC), y) -OPTS += -DUSE_VNC -RFLAGS += -DUSE_VNC + OPTS += -DUSE_VNC + RFLAGS += -DUSE_VNC ifneq ($(VNC_PATH), ) - OPTS += -I$(VNC_PATH)\INCLUDE - VNCLIB := -L$(VNC_PATH)\LIB + OPTS += -I$(VNC_PATH)\INCLUDE + VNCLIB := -L$(VNC_PATH)\LIB endif -VNCLIB += -lvncserver -VNCOBJ := vnc.o vnc_keymap.o + VNCLIB += -lvncserver + VNCOBJ := vnc.o vnc_keymap.o endif ifeq ($(MINITRACE), y) -OPTS += -DMTR_ENABLED -RFLAGS += -DMTR_ENABLED -MINITRACEOBJ := minitrace.o + OPTS += -DMTR_ENABLED + RFLAGS += -DMTR_ENABLED + MINITRACEOBJ := minitrace.o endif ifeq ($(FAUDIO), y) -OPTS += -DUSE_FAUDIO + OPTS += -DUSE_FAUDIO endif # Options for the DEV branch. ifeq ($(DEV_BRANCH), y) -OPTS += -DDEV_BRANCH -RFLAGS += -DDEV_BRANCH -DEVBROBJ := + OPTS += -DDEV_BRANCH + RFLAGS += -DDEV_BRANCH + DEVBROBJ := -ifeq ($(AMD_K5), y) -OPTS += -DUSE_AMD_K5 -endif + ifeq ($(AMD_K5), y) + OPTS += -DUSE_AMD_K5 + endif -ifeq ($(AN430TX), y) -OPTS += -DUSE_AN430TX -endif + ifeq ($(AN430TX), y) + OPTS += -DUSE_AN430TX + endif -ifeq ($(CYRIX_6X86), y) -OPTS += -DUSE_CYRIX_6X86 -endif + ifeq ($(CYRIX_6X86), y) + OPTS += -DUSE_CYRIX_6X86 + endif -ifeq ($(DESKPRO386), y) -OPTS += -DUSE_DESKPRO386 -endif + ifeq ($(DESKPRO386), y) + OPTS += -DUSE_DESKPRO386 + endif -ifeq ($(GUSMAX), y) -OPTS += -DUSE_GUSMAX -endif + ifeq ($(GUSMAX), y) + OPTS += -DUSE_GUSMAX + endif -ifeq ($(ISAMEM_RAMPAGE), y) -OPTS += -DUSE_ISAMEM_RAMPAGE -endif + ifeq ($(ISAMEM_RAMPAGE), y) + OPTS += -DUSE_ISAMEM_RAMPAGE + endif -ifeq ($(ISAMEM_IAB), y) -OPTS += -DUSE_ISAMEM_IAB -endif + ifeq ($(ISAMEM_IAB), y) + OPTS += -DUSE_ISAMEM_IAB + endif -ifeq ($(ISAMEM_BRAT), y) -OPTS += -DUSE_ISAMEM_BRAT -endif + ifeq ($(ISAMEM_BRAT), y) + OPTS += -DUSE_ISAMEM_BRAT + endif -ifeq ($(LASERXT), y) -OPTS += -DUSE_LASERXT -DEVBROBJ += m_xt_laserxt.o -endif + ifeq ($(LASERXT), y) + OPTS += -DUSE_LASERXT + DEVBROBJ += m_xt_laserxt.o + endif -ifeq ($(MGA), y) -OPTS += -DUSE_MGA -DEVBROBJ += vid_mga.o -endif + ifeq ($(MGA), y) + OPTS += -DUSE_MGA + DEVBROBJ += vid_mga.o + endif -ifeq ($(OPEN_AT), y) -OPTS += -DUSE_OPEN_AT -endif + ifeq ($(OPEN_AT), y) + OPTS += -DUSE_OPEN_AT + endif -ifeq ($(PAS16), y) -OPTS += -DUSE_PAS16 -DEVBROBJ += snd_pas16.o -endif + ifeq ($(PAS16), y) + OPTS += -DUSE_PAS16 + DEVBROBJ += snd_pas16.o + endif -ifeq ($(SIO_DETECT), y) -OPTS += -DUSE_SIO_DETECT -DEVBROBJ += sio_detect.o -endif + ifeq ($(SIO_DETECT), y) + OPTS += -DUSE_SIO_DETECT + DEVBROBJ += sio_detect.o + endif -ifeq ($(VGAWONDER), y) -OPTS += -DUSE_VGAWONDER -endif + ifeq ($(VGAWONDER), y) + OPTS += -DUSE_VGAWONDER + endif -ifeq ($(XL24), y) -OPTS += -DUSE_XL24 -endif + ifeq ($(XL24), y) + OPTS += -DUSE_XL24 + endif -ifeq ($(OLIVETTI), y) -OPTS += -DUSE_OLIVETTI -DEVBROBJ += olivetti_eva.o -endif - -ifeq ($(GDBSTUB), y) -OPTS += -DUSE_GDBSTUB -DEVBROBJ += gdbstub.o -endif + ifeq ($(OLIVETTI), y) + OPTS += -DUSE_OLIVETTI + DEVBROBJ += olivetti_eva.o + endif + ifeq ($(GDBSTUB), y) + OPTS += -DUSE_GDBSTUB + DEVBROBJ += gdbstub.o + endif endif # Final versions of the toolchain flags. -CFLAGS := $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ - -fno-strict-aliasing +CFLAGS := $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ + $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ + -fno-strict-aliasing # Add freetyp2 references through pkgconfig -CFLAGS := $(CFLAGS) `pkg-config --cflags freetype2` +CFLAGS := $(CFLAGS) `pkg-config --cflags freetype2` -CXXFLAGS := $(CFLAGS) +CXXFLAGS := $(CFLAGS) + +CFLAGS += -Werror=implicit-int -Werror=implicit-function-declaration \ + -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition ######################################################################### -# Create the (final) list of objects to build. # +# Create the (final) list of objects to build. # ######################################################################### -MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ - nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo8.o \ - usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \ - $(VNCOBJ) +MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ + nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo8.o \ + usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \ + $(VNCOBJ) -MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o +MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o -CPUOBJ := $(DYNARECOBJ) \ - $(CGTOBJ) \ - cpu.o cpu_table.o fpu.o x86.o \ - 8080.o 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \ - x86seg.o x87.o x87_timings.o +CPUOBJ := $(DYNARECOBJ) \ + $(CGTOBJ) \ + cpu.o cpu_table.o fpu.o x86.o \ + 8080.o 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \ + x86seg.o x87.o x87_timings.o -CHIPSETOBJ := 82c100.o acc2168.o \ - contaq_82c59x.o \ - cs4031.o cs8230.o \ - ali1429.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \ - gc100.o headland.o \ - ims8848.o intel_82335.o intel_420ex.o intel_4x0.o intel_i450kx.o intel_sio.o intel_piix.o \ - ioapic.o \ - neat.o \ - opti283.o opti291.o opti391.o opti495.o opti822.o opti895.o opti5x7.o \ - scamp.o scat.o \ - stpc.o \ - wd76c10.o vl82c480.o \ - umc_8886.o umc_hb4.o \ - via_vt82c49x.o via_vt82c505.o via_apollo.o via_pipc.o \ - sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o sis_5511.o sis_5571.o +CHIPSETOBJ := 82c100.o acc2168.o \ + contaq_82c59x.o \ + cs4031.o cs8230.o \ + ali1429.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \ + gc100.o headland.o \ + ims8848.o intel_82335.o intel_420ex.o intel_4x0.o intel_i450kx.o intel_sio.o intel_piix.o \ + ioapic.o \ + neat.o \ + opti283.o opti291.o opti391.o opti495.o opti822.o opti895.o opti5x7.o \ + scamp.o scat.o \ + stpc.o \ + wd76c10.o vl82c480.o \ + umc_8886.o umc_hb4.o \ + via_vt82c49x.o via_vt82c505.o via_apollo.o via_pipc.o \ + sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o sis_5511.o sis_5571.o -MCHOBJ := machine.o machine_table.o \ - m_xt.o m_xt_compaq.o \ - m_xt_philips.o \ - m_xt_t1000.o m_xt_t1000_vid.o \ - m_xt_xi8088.o m_xt_zenith.o \ - m_pcjr.o \ - m_amstrad.o m_europc.o \ - m_elt.o \ - m_xt_olivetti.o m_tandy.o m_v86p.o \ - m_at.o m_at_commodore.o \ - m_at_t3100e.o m_at_t3100e_vid.o \ - m_ps1.o m_ps1_hdc.o \ - m_ps2_isa.o m_ps2_mca.o \ - m_at_compaq.o \ - m_at_286_386sx.o m_at_386dx_486.o \ - m_at_socket4.o m_at_socket5.o m_at_socket7_3v.o m_at_socket7.o m_at_sockets7.o \ - m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \ - m_at_misc.o +MCHOBJ := machine.o machine_table.o \ + m_xt.o m_xt_compaq.o \ + m_xt_philips.o \ + m_xt_t1000.o m_xt_t1000_vid.o \ + m_xt_xi8088.o m_xt_zenith.o \ + m_pcjr.o \ + m_amstrad.o m_europc.o \ + m_elt.o \ + m_xt_olivetti.o m_tandy.o m_v86p.o \ + m_at.o m_at_commodore.o \ + m_at_t3100e.o m_at_t3100e_vid.o \ + m_ps1.o m_ps1_hdc.o \ + m_ps2_isa.o m_ps2_mca.o \ + m_at_compaq.o \ + m_at_286_386sx.o m_at_386dx_486.o \ + m_at_socket4.o m_at_socket5.o m_at_socket7_3v.o m_at_socket7.o m_at_sockets7.o \ + m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \ + m_at_misc.o ifeq ($(NEW_KBC), y) -DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ - ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ - clock_ics9xxx.o isapnp.o \ - i2c.o i2c_gpio.o smbus_ali7101.o smbus_piix4.o \ - keyboard.o \ - keyboard_xt.o kbc_at.o kbd_at.o \ - mouse.o \ - mouse_bus.o \ - mouse_serial.o mouse_ps2.o \ - phoenix_486_jumper.o + KBCOBJ := kbc_at.o kbd_at.o else -DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ - ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ - clock_ics9xxx.o isapnp.o \ - i2c.o i2c_gpio.o smbus_ali7101.o smbus_piix4.o \ - keyboard.o \ - keyboard_xt.o keyboard_at.o \ - mouse.o \ - mouse_bus.o \ - mouse_serial.o mouse_ps2.o \ - phoenix_486_jumper.o + KBCOBJ := keyboard_at.o endif -SIOOBJ := sio_acc3221.o sio_ali5123.o \ - sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ - sio_fdc37c67x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ - sio_it8661f.o \ - sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \ - sio_prime3b.o sio_prime3c.o \ - sio_w83787f.o \ - sio_w83877f.o sio_w83977f.o \ - sio_um8669f.o \ - sio_vt82c686.o +DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ + ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ + clock_ics9xxx.o isapnp.o \ + i2c.o i2c_gpio.o smbus_ali7101.o smbus_piix4.o \ + keyboard.o \ + keyboard_xt.o $(KBCOBJ) \ + mouse.o \ + mouse_bus.o \ + mouse_serial.o mouse_ps2.o \ + phoenix_486_jumper.o -FDDOBJ := fdd.o fdc.o fdc_magitronic.o fdc_pii15xb.o \ - fdi2raw.o \ - fdd_common.o fdd_86f.o \ - fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \ - fdd_mfm.o fdd_td0.o +SIOOBJ := sio_acc3221.o sio_ali5123.o \ + sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ + sio_fdc37c67x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ + sio_it8661f.o \ + sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \ + sio_prime3b.o sio_prime3c.o \ + sio_w83787f.o \ + sio_w83877f.o sio_w83977f.o \ + sio_um8669f.o \ + sio_vt82c686.o -GAMEOBJ := gameport.o \ - joystick_standard.o joystick_ch_flightstick_pro.o \ - joystick_sw_pad.o joystick_tm_fcs.o +FDDOBJ := fdd.o fdc.o fdc_magitronic.o fdc_pii15xb.o \ + fdi2raw.o \ + fdd_common.o fdd_86f.o \ + fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \ + fdd_mfm.o fdd_td0.o -HDDOBJ := hdd.o \ - hdd_image.o hdd_table.o \ - hdc.o \ - hdc_st506_xt.o hdc_st506_at.o \ - hdc_xta.o \ - hdc_esdi_at.o hdc_esdi_mca.o \ - hdc_xtide.o hdc_ide.o \ - hdc_ide_opti611.o \ - hdc_ide_cmd640.o hdc_ide_cmd646.o \ - hdc_ide_sff8038i.o +GAMEOBJ := gameport.o \ + joystick_standard.o joystick_ch_flightstick_pro.o \ + joystick_sw_pad.o joystick_tm_fcs.o + +HDDOBJ := hdd.o \ + hdd_image.o hdd_table.o \ + hdc.o \ + hdc_st506_xt.o hdc_st506_at.o \ + hdc_xta.o \ + hdc_esdi_at.o hdc_esdi_mca.o \ + hdc_xtide.o hdc_ide.o \ + hdc_ide_opti611.o \ + hdc_ide_cmd640.o hdc_ide_cmd646.o \ + hdc_ide_sff8038i.o MINIVHDOBJ := cwalk.o libxml2_encoding.o minivhd_convert.o \ - minivhd_create.o minivhd_io.o minivhd_manage.o \ - minivhd_struct_rw.o minivhd_util.o + minivhd_create.o minivhd_io.o minivhd_manage.o \ + minivhd_struct_rw.o minivhd_util.o -CDROMOBJ := cdrom.o \ - cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o cdrom_mitsumi.o +CDROMOBJ := cdrom.o \ + cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o cdrom_mitsumi.o -ZIPOBJ := zip.o +ZIPOBJ := zip.o -MOOBJ := mo.o +MOOBJ := mo.o -SCSIOBJ := scsi.o scsi_device.o \ - scsi_cdrom.o scsi_disk.o \ - scsi_x54x.o \ - scsi_aha154x.o scsi_buslogic.o \ - scsi_ncr5380.o scsi_ncr53c8xx.o \ - scsi_pcscsi.o scsi_spock.o +SCSIOBJ := scsi.o scsi_device.o \ + scsi_cdrom.o scsi_disk.o \ + scsi_x54x.o \ + scsi_aha154x.o scsi_buslogic.o \ + scsi_ncr5380.o scsi_ncr53c8xx.o \ + scsi_pcscsi.o scsi_spock.o -NETOBJ := network.o \ - net_pcap.o \ - net_slirp.o tinyglib.o \ - arp_table.o bootp.o cksum.o dnssearch.o if.o ip_icmp.o ip_input.o \ - ip_output.o mbuf.o misc.o sbuf.o slirp.o socket.o tcp_input.o \ - tcp_output.o tcp_subr.o tcp_timer.o udp.o util.o version.o \ - net_dp8390.o \ - net_3c503.o net_ne2000.o \ - net_pcnet.o net_wd8003.o \ - net_plip.o net_event.o +NETOBJ := network.o \ + net_pcap.o \ + net_slirp.o tinyglib.o \ + arp_table.o bootp.o cksum.o dnssearch.o if.o ip_icmp.o ip_input.o \ + ip_output.o mbuf.o misc.o sbuf.o slirp.o socket.o tcp_input.o \ + tcp_output.o tcp_subr.o tcp_timer.o udp.o util.o version.o \ + net_dp8390.o net_3c501.o \ + net_3c503.o net_ne2000.o \ + net_pcnet.o net_wd8003.o \ + net_plip.o net_event.o -PRINTOBJ := png.o prt_cpmap.o \ - prt_escp.o prt_text.o prt_ps.o +PRINTOBJ := png.o prt_cpmap.o \ + prt_escp.o prt_text.o prt_ps.o -SNDOBJ := sound.o \ - snd_opl.o snd_opl_nuked.o snd_opl_ymfm.o \ - ymfm_adpcm.o ymfm_misc.o ymfm_opl.o ymfm_opm.o \ - ymfm_opn.o ymfm_opq.o ymfm_opz.o ymfm_pcm.o ymfm_ssg.o \ - snd_resid.o \ - convolve.o convolve-sse.o envelope.o extfilt.o \ - filter.o pot.o sid.o voice.o wave6581__ST.o \ - wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ - wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o \ - midi.o \ - snd_speaker.o \ - snd_pssj.o \ - snd_ps1.o \ - snd_lpt_dac.o snd_lpt_dss.o \ - snd_adlib.o snd_adlibgold.o snd_ad1848.o snd_audiopci.o \ - snd_ac97_codec.o snd_ac97_via.o \ - snd_azt2316a.o snd_cs423x.o snd_cmi8x38.o \ - snd_cms.o \ - snd_gus.o \ - snd_sb.o snd_sb_dsp.o \ - snd_emu8k.o snd_mpu401.o \ - snd_sn76489.o snd_ssi2001.o \ - snd_wss.o \ - snd_ym7128.o +SNDOBJ := sound.o \ + snd_opl.o snd_opl_nuked.o snd_opl_ymfm.o \ + ymfm_adpcm.o ymfm_misc.o ymfm_opl.o ymfm_opm.o \ + ymfm_opn.o ymfm_opq.o ymfm_opz.o ymfm_pcm.o ymfm_ssg.o \ + snd_resid.o \ + convolve.o convolve-sse.o envelope.o extfilt.o \ + filter.o pot.o sid.o voice.o wave6581__ST.o \ + wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ + wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ + wave8580_PST.o wave.o \ + midi.o \ + snd_speaker.o \ + snd_pssj.o \ + snd_ps1.o \ + snd_lpt_dac.o snd_lpt_dss.o \ + snd_adlib.o snd_adlibgold.o snd_ad1848.o snd_audiopci.o \ + snd_ac97_codec.o snd_ac97_via.o \ + snd_azt2316a.o snd_cs423x.o \ + snd_optimc.o snd_cmi8x38.o \ + snd_cms.o \ + snd_gus.o \ + snd_sb.o snd_sb_dsp.o \ + snd_emu8k.o snd_mpu401.o \ + snd_sn76489.o snd_ssi2001.o \ + snd_wss.o \ + snd_ym7128.o -VIDOBJ := agpgart.o video.o \ - vid_table.o \ - vid_cga.o vid_cga_comp.o \ - vid_compaq_cga.o \ - vid_mda.o \ - vid_hercules.o vid_herculesplus.o vid_incolor.o \ - vid_colorplus.o \ - vid_genius.o \ - vid_pgc.o vid_im1024.o \ - vid_sigma.o \ - vid_wy700.o \ - vid_ega.o vid_ega_render.o \ - vid_svga.o vid_svga_render.o \ - vid_8514a.o \ - vid_ddc.o \ - vid_vga.o \ - vid_ati_eeprom.o \ - vid_ati18800.o vid_ati28800.o \ - vid_ati_mach64.o vid_ati68860_ramdac.o \ - vid_bt48x_ramdac.o \ - vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ - vid_cl54xx.o \ - vid_et4000.o vid_sc1148x_ramdac.o \ - vid_sc1502x_ramdac.o \ - vid_et4000w32.o vid_stg_ramdac.o \ - vid_ht216.o \ - vid_oak_oti.o \ - vid_paradise.o \ - vid_rtg310x.o \ - vid_ti_cf62011.o \ - vid_f82c425.o \ - vid_tvga.o \ - vid_tgui9440.o vid_tkd8001_ramdac.o \ - vid_att20c49x_ramdac.o \ - vid_att2xc498_ramdac.o \ - vid_s3.o vid_s3_virge.o \ - vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \ - vid_ogc.o \ - vid_nga.o \ - vid_tvp3026_ramdac.o \ - vid_xga.o +VIDOBJ := agpgart.o video.o \ + vid_table.o \ + vid_cga.o vid_cga_comp.o \ + vid_compaq_cga.o \ + vid_mda.o \ + vid_hercules.o vid_herculesplus.o vid_incolor.o \ + vid_colorplus.o \ + vid_genius.o \ + vid_pgc.o vid_im1024.o \ + vid_sigma.o \ + vid_wy700.o \ + vid_ega.o vid_ega_render.o \ + vid_svga.o vid_svga_render.o \ + vid_8514a.o \ + vid_ddc.o \ + vid_vga.o \ + vid_ati_eeprom.o \ + vid_ati18800.o vid_ati28800.o \ + vid_ati_mach64.o vid_ati68860_ramdac.o \ + vid_bt48x_ramdac.o \ + vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ + vid_cl54xx.o \ + vid_et3000.o \ + vid_et4000.o vid_sc1148x_ramdac.o \ + vid_sc1502x_ramdac.o \ + vid_et4000w32.o vid_stg_ramdac.o \ + vid_ht216.o \ + vid_oak_oti.o \ + vid_paradise.o \ + vid_rtg310x.o \ + vid_ti_cf62011.o \ + vid_f82c425.o \ + vid_tvga.o \ + vid_tgui9440.o vid_tkd8001_ramdac.o \ + vid_att20c49x_ramdac.o \ + vid_att2xc498_ramdac.o \ + vid_s3.o vid_s3_virge.o \ + vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \ + vid_ogc.o \ + vid_nga.o \ + vid_tvp3026_ramdac.o \ + vid_xga.o -VOODOOOBJ := vid_voodoo.o vid_voodoo_banshee.o \ - vid_voodoo_banshee_blitter.o \ - vid_voodoo_blitter.o \ - vid_voodoo_display.o vid_voodoo_fb.o \ - vid_voodoo_fifo.o vid_voodoo_reg.o \ - vid_voodoo_render.o vid_voodoo_setup.o \ - vid_voodoo_texture.o +VOODOOOBJ := vid_voodoo.o vid_voodoo_banshee.o \ + vid_voodoo_banshee_blitter.o \ + vid_voodoo_blitter.o \ + vid_voodoo_display.o vid_voodoo_fb.o \ + vid_voodoo_fifo.o vid_voodoo_reg.o \ + vid_voodoo_render.o vid_voodoo_setup.o \ + vid_voodoo_texture.o -PLATOBJ := win.o \ - win_dynld.o \ - win_cdrom.o win_keyboard.o \ - win_mouse.o +PLATOBJ := win.o \ + win_dynld.o \ + win_cdrom.o win_keyboard.o \ + win_mouse.o -UIOBJ := win_ui.o win_icon.o win_stbar.o discord.o \ - win_sdl.o win_opengl.o win_opengl_glslp.o glad.o \ - win_dialog.o win_about.o \ - win_settings.o win_devconf.o win_snd_gain.o win_specify_dim.o win_preferences.o \ - win_new_floppy.o win_jsconf.o \ - win_media_menu.o win_toolbar.o +UIOBJ := win_ui.o win_icon.o win_stbar.o discord.o \ + win_sdl.o win_opengl.o win_opengl_glslp.o glad.o \ + win_dialog.o win_about.o \ + win_settings.o win_devconf.o win_snd_gain.o win_specify_dim.o win_preferences.o \ + win_new_floppy.o win_jsconf.o \ + win_media_menu.o win_toolbar.o ifeq ($(DINPUT), y) - PLATOBJ += win_joystick.o + PLATOBJ += win_joystick.o else - PLATOBJ += win_joystick_rawinput.o + PLATOBJ += win_joystick_rawinput.o endif ifeq ($(OPENAL), y) - SNDOBJ += openal.o + SNDOBJ += openal.o else - SNDOBJ += xaudio2.o + SNDOBJ += xaudio2.o endif -OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ - $(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \ - $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \ - $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ) +OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ + $(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \ + $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \ + $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ) ifdef EXOBJ -OBJ += $(EXOBJ) + OBJ += $(EXOBJ) endif ifeq ($(OPENAL), y) -LIBS := -mwindows -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 + LIBS := -mwindows -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 else -ifeq ($(FAUDIO), y) -LIBS := -mwindows -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 -else -LIBS := -mwindows -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 -endif + ifeq ($(FAUDIO), y) + LIBS := -mwindows -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 + else + LIBS := -mwindows -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 + endif endif ifeq ($(RTMIDI), y) - SNDOBJ += midi_rtmidi.o - OPTS += -DUSE_RTMIDI - LIBS += -lrtmidi + SNDOBJ += midi_rtmidi.o + OPTS += -DUSE_RTMIDI + LIBS += -lrtmidi endif ifeq ($(VNC), y) -LIBS += $(VNCLIB) -lws2_32 + LIBS += $(VNCLIB) -lws2_32 endif -LIBS += -lpng -lz -lwsock32 -liphlpapi -lpsapi -lhid -lsetupapi -luxtheme -static -lstdc++ +LIBS += -lpng -lz -lwsock32 -liphlpapi -lpsapi -lhid -lsetupapi -luxtheme -static -lstdc++ ifneq ($(X64), y) -ifneq ($(ARM64), y) -LIBS += -Wl,--large-address-aware -endif + ifneq ($(ARM64), y) + LIBS += -Wl,--large-address-aware + endif endif ifeq ($(ARM64), y) -LIBS += -lgcc + LIBS += -lgcc endif ifeq ($(DINPUT), y) - LIBS += -ldinput8 + LIBS += -ldinput8 endif -LIBS += -static +LIBS += -static # Build module rules. ifeq ($(AUTODEP), y) -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -c $< +%.o: %.c + @echo $< + @$(CC) $(CFLAGS) $(DEPS) -c $< -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< +%.o: %.cc + @echo $< + @$(CPP) $(CXXFLAGS) $(DEPS) -c $< -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< +%.o: %.cpp + @echo $< + @$(CPP) $(CXXFLAGS) $(DEPS) -c $< else -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) -c $< +%.o: %.c + @echo $< + @$(CC) $(CFLAGS) -c $< -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) -c $< +%.o: %.cc + @echo $< + @$(CPP) $(CXXFLAGS) -c $< -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) -c $< +%.o: %.cpp + @echo $< + @$(CPP) $(CXXFLAGS) -c $< -%.d: %.c $(wildcard $*.d) - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -E $< >/dev/null +%.d: %.c $(wildcard $*.d) + @echo $< + @$(CC) $(CFLAGS) $(DEPS) -E $< >/dev/null -%.d: %.cc $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >/dev/null +%.d: %.cc $(wildcard $*.d) + @echo $< + @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >/dev/null -%.d: %.cpp $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >/dev/null +%.d: %.cpp $(wildcard $*.d) + @echo $< + @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >/dev/null endif # Suppress false positive warnings in vid_voodoo_codegen_x86[-64].h @@ -847,59 +844,59 @@ ifneq ($(CLANG), y) $(VOODOOOBJ): CFLAGS += -Wstringop-overflow=0 endif -all: $(PROG).exe +all: $(PROG).exe -86Box.res: 86Box.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) $(EXTRAS) -i $< -o 86Box.res +86Box.res: 86Box.rc + @echo Processing $< + @$(WINDRES) $(RFLAGS) $(EXTRAS) -i $< -o 86Box.res -$(PROG).exe: $(OBJ) 86Box.res - @echo Linking $(PROG).exe .. - @$(CC) $(LDFLAGS) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe +$(PROG).exe: $(OBJ) 86Box.res + @echo Linking $(PROG).exe .. + @$(CC) $(LDFLAGS) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe ifneq ($(DEBUG), y) - @$(STRIP) $(PROG).exe + @$(STRIP) $(PROG).exe endif -pcap_if.res: pcap_if.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) -i $< -o pcap_if.res +pcap_if.res: pcap_if.rc + @echo Processing $< + @$(WINDRES) $(RFLAGS) -i $< -o pcap_if.res -pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res - @echo Linking pcap_if.exe .. - @$(CC) $(LDFLAGS) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res +pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res + @echo Linking pcap_if.exe .. + @$(CC) $(LDFLAGS) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res ifneq ($(DEBUG), y) - @$(STRIP) pcap_if.exe + @$(STRIP) pcap_if.exe endif -hello.exe: hello.o - $(CXX) $(LDFLAGS) -o hello.exe hello.o $(LIBS) +hello.exe: hello.o + $(CXX) $(LDFLAGS) -o hello.exe hello.o $(LIBS) ifneq ($(DEBUG), y) - @$(STRIP) hello.exe + @$(STRIP) hello.exe endif clean: - @echo Cleaning objects.. - @-rm -f *.o 2>/dev/null - @-rm -f *.res 2>/dev/null + @echo Cleaning objects.. + @-rm -f *.o 2>/dev/null + @-rm -f *.res 2>/dev/null -clobber: clean - @echo Cleaning executables.. - @-rm -f *.d 2>/dev/null - @-rm -f *.exe 2>/dev/null -# @-rm -f $(DEPFILE) 2>/dev/null +clobber: clean + @echo Cleaning executables.. + @-rm -f *.d 2>/dev/null + @-rm -f *.exe 2>/dev/null +# @-rm -f $(DEPFILE) 2>/dev/null ifneq ($(AUTODEP), y) depclean: - @-rm -f $(DEPFILE) 2>/dev/null - @echo Creating dependencies.. - @echo # Run "make depends" to re-create this file. >$(DEPFILE) + @-rm -f $(DEPFILE) 2>/dev/null + @echo Creating dependencies.. + @echo # Run "make depends" to re-create this file. >$(DEPFILE) -depends: DEPOBJ=$(OBJ:%.o=%.d) -depends: depclean $(OBJ:%.o=%.d) - @-cat $(DEPOBJ) >>$(DEPFILE) - @-rm -f $(DEPOBJ) +depends: DEPOBJ=$(OBJ:%.o=%.d) +depends: depclean $(OBJ:%.o=%.d) + @-cat $(DEPOBJ) >>$(DEPFILE) + @-rm -f $(DEPOBJ) $(DEPFILE): endif diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc index 1c431281b..9b49fc01d 100644 --- a/src/win/languages/cs-CZ.rc +++ b/src/win/languages/cs-CZ.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Schovat stavový řádek", IDM_VID_HIDE_STATUS_BAR MENUITEM "Schovat panel &nástrojů", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Měnitelná velikost okna", IDM_VID_RESIZE MENUITEM "&Pamatovat velikost a pozici", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -177,7 +178,7 @@ BEGIN MENUITEM "&Načíst znova předchozí obraz", IDM_CDROM_RELOAD MENUITEM SEPARATOR MENUITEM "&Obraz...", IDM_CDROM_IMAGE - MENUITEM "&Složka", IDM_CDROM_DIR + MENUITEM "&Složka...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Dynamický překladač" #define STR_VIDEO "Grafika:" +#define STR_VIDEO_2 "Grafika 2:" #define STR_VOODOO "Použít grafický akcelerátor Voodoo" #define STR_IBM8514 "Grafika IBM 8514/a" #define STR_XGA "Grafika XGA" @@ -333,6 +335,7 @@ END #define STR_BUS "Sběrnice:" #define STR_CHANNEL "Kanál:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Zadat..." #define STR_SECTORS "Sektory:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Kontrola BPB" - IDS_2088 "KB" - IDS_2089 "Nastala chyba při inicializaci video rendereru." - IDS_2090 "Výchozí" - IDS_2091 "%i čekací stav(y)" - IDS_2092 "Typ" - IDS_2093 "Nastala chyba při inicializaci knihovny PCap" - IDS_2094 "Nebyla nalezena žádná PCap zařízení" - IDS_2095 "Neplatné PCap zařízení" - IDS_2096 "Standardní 2tlačítkový joystick" - IDS_2097 "Standardní 4tlačítkový joystick" - IDS_2098 "Standardní 6tlačítkový joystick" - IDS_2099 "Standardní 8tlačítkový joystick" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Žadné" - IDS_2104 "Nebylo možné nahrát klávesnicové zkratky." - IDS_2105 "Nebylo možné zaregistrovat raw input." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Disketová mechanika %i (%s): %ls" - IDS_2109 "Všechny obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Rozšířené sektorové obrazy (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Základní sektorové obrazy (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Obrazy magnetického toku (*.FDI)\0*.FDI\0Obrazy povrchu (*.86F;*.MFM)\0*.86F;*.MFM\0Všechny soubory (*.*)\0*.*\0" - IDS_2110 "Nastala chyba při inicializaci knihovny FreeType" - IDS_2111 "Nastala chyba při inicializaci knihovny SDL, je potřeba SDL2.dll" - IDS_2112 "Opravdu chcete resetovat emulovaný počítač?" - IDS_2113 "Opravdu chcete ukončit 86Box?" - IDS_2114 "Nastala chyba při inicializaci knihovny Ghostscript" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Všechny soubory (*.*)\0*.*\0" - IDS_2117 "Vítejte v programu 86Box!" - IDS_2118 "Vestavěný řadič" - IDS_2119 "Ukončit" - IDS_2120 "Nebyly nalezeny žádné obrazy ROM" - IDS_2121 "Chcete uložit nastavení?" - IDS_2122 "Pokračováním se resetuje emulovaný počítač." - IDS_2123 "Uložit" - IDS_2124 "O programu 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Kontrola BPB" + IDS_2089 "KB" + IDS_2090 "Nastala chyba při inicializaci video rendereru." + IDS_2091 "Výchozí" + IDS_2092 "%i čekací stav(y)" + IDS_2093 "Typ" + IDS_2094 "Nastala chyba při inicializaci knihovny PCap" + IDS_2095 "Nebyla nalezena žádná PCap zařízení" + IDS_2096 "Neplatné PCap zařízení" + IDS_2097 "Standardní 2tlačítkový joystick" + IDS_2098 "Standardní 4tlačítkový joystick" + IDS_2099 "Standardní 6tlačítkový joystick" + IDS_2100 "Standardní 8tlačítkový joystick" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Žadné" + IDS_2105 "Nebylo možné nahrát klávesnicové zkratky." + IDS_2106 "Nebylo možné zaregistrovat raw input." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Disketová mechanika %i (%s): %ls" + IDS_2110 "Všechny obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Rozšířené sektorové obrazy (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Základní sektorové obrazy (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Obrazy magnetického toku (*.FDI)\0*.FDI\0Obrazy povrchu (*.86F;*.MFM)\0*.86F;*.MFM\0Všechny soubory (*.*)\0*.*\0" + IDS_2111 "Nastala chyba při inicializaci knihovny FreeType" + IDS_2112 "Nastala chyba při inicializaci knihovny SDL, je potřeba SDL2.dll" + IDS_2113 "Opravdu chcete resetovat emulovaný počítač?" + IDS_2114 "Opravdu chcete ukončit 86Box?" + IDS_2115 "Nastala chyba při inicializaci knihovny Ghostscript" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Všechny soubory (*.*)\0*.*\0" + IDS_2118 "Vítejte v programu 86Box!" + IDS_2119 "Vestavěný řadič" + IDS_2120 "Ukončit" + IDS_2121 "Nebyly nalezeny žádné obrazy ROM" + IDS_2122 "Chcete uložit nastavení?" + IDS_2123 "Pokračováním se resetuje emulovaný počítač." + IDS_2124 "Uložit" + IDS_2125 "O programu 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "Emulátor starých počítačů\n\nAutoři: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." - IDS_2127 "OK" - IDS_2128 "Hardware není dostupný" + IDS_2127 "Emulátor starých počítačů\n\nAutoři: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." + IDS_2128 "OK" + IDS_2129 "Hardware není dostupný" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Ujistěte se, že je nainstalován " LIB_NAME_PCAP " a používáte síťové připojení s ním kompatibilní." - IDS_2130 "Neplatná konfigurace" + IDS_2130 "Ujistěte se, že je nainstalován " LIB_NAME_PCAP " a používáte síťové připojení s ním kompatibilní." + IDS_2131 "Neplatná konfigurace" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " je potřeba pro emulaci ESC/P tiskáren." + IDS_2132 LIB_NAME_FREETYPE " je potřeba pro emulaci ESC/P tiskáren." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." + IDS_2133 LIB_NAME_GS " je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " je potřeba pro MIDI výstup přes knihovnu FluidSynth." - IDS_2134 "Vstup do režimu celé obrazovky" - IDS_2135 "Nezobrazovat dále tuto zprávu" - IDS_2136 "Neukončovat" - IDS_2137 "Resetovat" - IDS_2138 "Neresetovat" - IDS_2139 "Obraz magnetooptického disku (*.IM?;*.MDI)\0*.IM?;*.MDI\0Všechny soubory (*.*)\0*.*\0" - IDS_2140 "Obraz CD-ROM disku (*.ISO;*.CUE)\0*.ISO;*.CUE\0Všechny soubory (*.*)\0*.*\0" - IDS_2141 "Konfigurace zařízení %hs" - IDS_2142 "Monitor je v režimu spánku" - IDS_2143 "Shadery OpenGL (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2144 "Možnosti OpenGL" - IDS_2145 "Pokoušíte se spustit nepodporovanou konfiguraci" - IDS_2146 "Pro tuto konfiguraci bylo vypnuto filtrování procesorů podle zvoleného počítače.\n\nToto umožňuje zvolit procesor, který by jinak se zvoleným počítačem nebyl kompatibilní. Můžou však nastat potíže s BIOSem nebo jiným softwarem.\n\nPovolení tohoto nastavení není oficiálně podporováno a jakákoliv hlášení o chybách mohou být uzavřeny jako neplatné." - IDS_2147 "Pokračovat" - IDS_2148 "Kazeta: %s" - IDS_2149 "Kazetové nahrávky (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Všechny soubory (*.*)\0*.*\0" - IDS_2150 "Cartridge %i: %ls" - IDS_2151 "Obrazy cartridge (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Všechny soubory (*.*)\0*.*\0" - IDS_2152 "Error initializing renderer" - IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2154 "Obnovit" - IDS_2155 "Pozastavit" - IDS_2156 "Stisknout Ctrl+Alt+Delete" - IDS_2157 "Stisknout Ctrl+Alt+Esc" - IDS_2158 "Resetovat" - IDS_2159 "Vypnout skrze rozhraní ACPI" - IDS_2160 "Nastavení" - IDS_2161 "Časná mechanika" + IDS_2134 LIB_NAME_FLUIDSYNTH " je potřeba pro MIDI výstup přes knihovnu FluidSynth." + IDS_2135 "Vstup do režimu celé obrazovky" + IDS_2136 "Nezobrazovat dále tuto zprávu" + IDS_2137 "Neukončovat" + IDS_2138 "Resetovat" + IDS_2139 "Neresetovat" + IDS_2140 "Obraz magnetooptického disku (*.IM?;*.MDI)\0*.IM?;*.MDI\0Všechny soubory (*.*)\0*.*\0" + IDS_2141 "Obraz CD-ROM disku (*.ISO;*.CUE)\0*.ISO;*.CUE\0Všechny soubory (*.*)\0*.*\0" + IDS_2142 "Konfigurace zařízení %hs" + IDS_2143 "Monitor je v režimu spánku" + IDS_2144 "Shadery OpenGL (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" + IDS_2145 "Možnosti OpenGL" + IDS_2146 "Pokoušíte se spustit nepodporovanou konfiguraci" + IDS_2147 "Pro tuto konfiguraci bylo vypnuto filtrování procesorů podle zvoleného počítače.\n\nToto umožňuje zvolit procesor, který by jinak se zvoleným počítačem nebyl kompatibilní. Můžou však nastat potíže s BIOSem nebo jiným softwarem.\n\nPovolení tohoto nastavení není oficiálně podporováno a jakákoliv hlášení o chybách mohou být uzavřeny jako neplatné." + IDS_2148 "Pokračovat" + IDS_2149 "Kazeta: %s" + IDS_2150 "Kazetové nahrávky (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Všechny soubory (*.*)\0*.*\0" + IDS_2151 "Cartridge %i: %ls" + IDS_2152 "Obrazy cartridge (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Všechny soubory (*.*)\0*.*\0" + IDS_2153 "Error initializing renderer" + IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + IDS_2155 "Obnovit" + IDS_2156 "Pozastavit" + IDS_2157 "Stisknout Ctrl+Alt+Delete" + IDS_2158 "Stisknout Ctrl+Alt+Esc" + IDS_2159 "Resetovat" + IDS_2160 "Vypnout skrze rozhraní ACPI" + IDS_2161 "Nastavení" + IDS_2162 "Časná mechanika" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc index ff67041b5..74199b6da 100644 --- a/src/win/languages/de-DE.rc +++ b/src/win/languages/de-DE.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Statusleiste ausblenden", IDM_VID_HIDE_STATUS_BAR MENUITEM "&Werkzeugleiste ausblenden", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Größenverstellbares Fenster", IDM_VID_RESIZE MENUITEM "&Größe && Position merken", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "L&eer", IDM_CDROM_EMPTY MENUITEM "&Voriges Image neu laden", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image", IDM_CDROM_IMAGE - MENUITEM "&Verzeichnis", IDM_CDROM_DIR + MENUITEM "&Image...", IDM_CDROM_IMAGE + MENUITEM "&Verzeichnis...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Dynamischer Recompiler" #define STR_VIDEO "Videokarte:" +#define STR_VIDEO_2 "Videokarte 2:" #define STR_VOODOO "Voodoo-Grafik" #define STR_IBM8514 "IBM 8514/a-Grafik" #define STR_XGA "XGA-Grafik" @@ -333,6 +335,7 @@ END #define STR_BUS "Bus:" #define STR_CHANNEL "Kanal:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Festlegen..." #define STR_SECTORS "Sektoren:" @@ -347,7 +350,7 @@ END #define STR_TURBO "Turbo-Timings" #define STR_CHECKBPB "BPB überprüfen" #define STR_CDROM_DRIVES "CD-ROM-Laufwerke:" -#define STR_CD_SPEED "Takt:" +#define STR_CD_SPEED "Geschwindigkeit:" #define STR_EARLY "Früheres Laufwerk" #define STR_MO_DRIVES "MO-Laufwerke:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "BPB prüfen" - IDS_2088 "KB" - IDS_2089 "Der Videorenderer konnte nicht initialisiert werden." - IDS_2090 "Standard" - IDS_2091 "%i Wartezustände" - IDS_2092 "Typ" - IDS_2093 "PCap konnte nicht eingerichtet werden" - IDS_2094 "Keine PCap-Geräte gefunden" - IDS_2095 "Ungültiges PCap-Gerät" - IDS_2096 "Standard 2-Tasten-Joystick(s)" - IDS_2097 "Standard 4-Tasten-Joystick" - IDS_2098 "Standard 6-Tasten-Joystick" - IDS_2099 "Standard 8-Tasten-Joystick" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Ohne" - IDS_2104 "Tastaturbeschleuniger konnten nicht geladen werden." - IDS_2105 "Roheingaben konnten nicht registriert werden." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Diskette %i (%s): %ls" - IDS_2109 "Alle Images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Fortgeschrittene Sektorimages (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basissektorimages (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Fluximages (*.FDI)\0*.FDI\0Oberflächenimages (*.86F;*.MFM)\0*.86F;*.MFM\0Alle Dateien (*.*)\0*.*\0" - IDS_2110 "FreeType konnte nicht initialisiert werden" - IDS_2111 "SDL konnte nicht initialisiert werden, die Datei SDL2.dll wird benötigt" - IDS_2112 "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" - IDS_2113 "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" - IDS_2114 "Ghostscript konnte nicht initialisiert werden" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "MO-Images (*.IM?;*.MDI)\0*.IM?;*.MDI\0Alle Dateien (*.*)\0*.*\0" - IDS_2117 "Willkommen bei 86Box!" - IDS_2118 "Interner Controller" - IDS_2119 "Beenden" - IDS_2120 "Keine ROMs gefunden" - IDS_2121 "Möchten Sie die Einstellungen speichern?" - IDS_2122 "Dies wird zu einem Hard-Reset des emulierten Systems führen." - IDS_2123 "Speichern" - IDS_2124 "Über 86Box" - IDS_2125 "86Box Version " EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "BPB prüfen" + IDS_2089 "KB" + IDS_2090 "Der Videorenderer konnte nicht initialisiert werden." + IDS_2091 "Standard" + IDS_2092 "%i Wartezustände" + IDS_2093 "Typ" + IDS_2094 "PCap konnte nicht eingerichtet werden" + IDS_2095 "Keine PCap-Geräte gefunden" + IDS_2096 "Ungültiges PCap-Gerät" + IDS_2097 "Standard 2-Tasten-Joystick(s)" + IDS_2098 "Standard 4-Tasten-Joystick" + IDS_2099 "Standard 6-Tasten-Joystick" + IDS_2100 "Standard 8-Tasten-Joystick" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Ohne" + IDS_2105 "Tastaturbeschleuniger konnten nicht geladen werden." + IDS_2106 "Roheingaben konnten nicht registriert werden." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Diskette %i (%s): %ls" + IDS_2110 "Alle Images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Fortgeschrittene Sektorimages (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basissektorimages (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Fluximages (*.FDI)\0*.FDI\0Oberflächenimages (*.86F;*.MFM)\0*.86F;*.MFM\0Alle Dateien (*.*)\0*.*\0" + IDS_2111 "FreeType konnte nicht initialisiert werden" + IDS_2112 "SDL konnte nicht initialisiert werden, die Datei SDL2.dll wird benötigt" + IDS_2113 "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" + IDS_2114 "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" + IDS_2115 "Ghostscript konnte nicht initialisiert werden" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "MO-Images (*.IM?;*.MDI)\0*.IM?;*.MDI\0Alle Dateien (*.*)\0*.*\0" + IDS_2118 "Willkommen bei 86Box!" + IDS_2119 "Interner Controller" + IDS_2120 "Beenden" + IDS_2121 "Keine ROMs gefunden" + IDS_2122 "Möchten Sie die Einstellungen speichern?" + IDS_2123 "Dies wird zu einem Hard-Reset des emulierten Systems führen." + IDS_2124 "Speichern" + IDS_2125 "Über 86Box" + IDS_2126 "86Box Version " EMU_VERSION - IDS_2126 "Ein Emulator für alte Computer\n\nAutoren: Sarah Walker, Miran Grča, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." - IDS_2127 "OK" - IDS_2128 "Hardware nicht verfügbar" + IDS_2127 "Ein Emulator für alte Computer\n\nAutoren: Sarah Walker, Miran Grča, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." + IDS_2128 "OK" + IDS_2129 "Hardware nicht verfügbar" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Bitte stellen Sie sicher, dass " LIB_NAME_PCAP " installiert ist und sie eine " LIB_NAME_PCAP "-kompatible Netzwerkverbindung nutzen." - IDS_2130 "Ungültige Konfiguration" + IDS_2130 "Bitte stellen Sie sicher, dass " LIB_NAME_PCAP " installiert ist und sie eine " LIB_NAME_PCAP "-kompatible Netzwerkverbindung nutzen." + IDS_2131 "Ungültige Konfiguration" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " wird für die ESC/P-Druckeremulation benötigt." + IDS_2132 LIB_NAME_FREETYPE " wird für die ESC/P-Druckeremulation benötigt." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." + IDS_2133 LIB_NAME_GS " wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " wird für die FluidSynth-MIDI-Ausgabe benötigt." - IDS_2134 "Vollbildmodus wird aktiviert" - IDS_2135 "Diese Nachricht nicht mehr anzeigen" - IDS_2136 "Nicht beenden" - IDS_2137 "Zurücksetzen" - IDS_2138 "Nicht zurücksetzen" - IDS_2139 "MO-Images (*.IM?;*.MDI)\0*.IM?;*.MDI\0Alle Dateien (*.*)\0*.*\0" - IDS_2140 "CD-ROM-Images (*.ISO;*.CUE)\0*.ISO;*.CUE\0Alle Dateien (*.*)\0*.*\0" - IDS_2141 "%hs-Gerätekonfiguration" - IDS_2142 "Monitor im Standbymodus" - IDS_2143 "OpenGL-Shader (*.GLSL)\0*.GLSL\0Alle Dateien (*.*)\0*.*\0" - IDS_2144 "OpenGL-Optionen" - IDS_2145 "Sie laden gerade eine nicht unterstützte Konfiguration" - IDS_2146 "Das Filtern der CPU-Typen basierend auf dem ausgewählten System ist für dieses System deaktiviert.\n\nDies ermöglicht es, dass man eine sonst nicht mit dem ausgewählten System inkompatible CPU auswählen kann. Allerdings kann dies zu Inkompatiblilitäten mit dem BIOS des Systems oder anderen Programmen kommen.\n\nDas Aktivieren dieser Einstellung wird nicht unterstützt und sämtliche Bugreports können als ""invalid"" geschlossen werden." - IDS_2147 "Fortfahren" - IDS_2148 "Kassette: %s" - IDS_2149 "Kassettenimages (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Alle Dateien (*.*)\0*.*\0" - IDS_2150 "Cartridge %i: %ls" - IDS_2151 "Cartridgeimages (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Alle Dateien (*.*)\0*.*\0" - IDS_2152 "Fehler bei der Rendererinitialisierung" - IDS_2153 "Der OpenGL (3.0-Kern)-Renderer konnte nicht initialisiert werden. Bitte benutzen Sie einen anderen Renderer." - IDS_2154 "Fortsetzen" - IDS_2155 "Pausieren" - IDS_2156 "Strg+Alt+Entf drücken" - IDS_2157 "Strg+Alt+Esc drücken" - IDS_2158 "Hard-Reset" - IDS_2159 "ACPI-basiertes Herunterfahren" - IDS_2160 "Optionen" - IDS_2161 "Früheres Laufwerk" + IDS_2134 LIB_NAME_FLUIDSYNTH " wird für die FluidSynth-MIDI-Ausgabe benötigt." + IDS_2135 "Vollbildmodus wird aktiviert" + IDS_2136 "Diese Nachricht nicht mehr anzeigen" + IDS_2137 "Nicht beenden" + IDS_2138 "Zurücksetzen" + IDS_2139 "Nicht zurücksetzen" + IDS_2140 "MO-Images (*.IM?;*.MDI)\0*.IM?;*.MDI\0Alle Dateien (*.*)\0*.*\0" + IDS_2141 "CD-ROM-Images (*.ISO;*.CUE)\0*.ISO;*.CUE\0Alle Dateien (*.*)\0*.*\0" + IDS_2142 "%hs-Gerätekonfiguration" + IDS_2143 "Monitor im Standbymodus" + IDS_2144 "OpenGL-Shader (*.GLSL)\0*.GLSL\0Alle Dateien (*.*)\0*.*\0" + IDS_2145 "OpenGL-Optionen" + IDS_2146 "Sie laden gerade eine nicht unterstützte Konfiguration" + IDS_2147 "Das Filtern der CPU-Typen basierend auf dem ausgewählten System ist für dieses System deaktiviert.\n\nDies ermöglicht es, dass man eine sonst nicht mit dem ausgewählten System inkompatible CPU auswählen kann. Allerdings kann dies zu Inkompatiblilitäten mit dem BIOS des Systems oder anderen Programmen kommen.\n\nDas Aktivieren dieser Einstellung wird nicht unterstützt und sämtliche Bugreports können als ""invalid"" geschlossen werden." + IDS_2148 "Fortfahren" + IDS_2149 "Kassette: %s" + IDS_2150 "Kassettenimages (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Alle Dateien (*.*)\0*.*\0" + IDS_2151 "Cartridge %i: %ls" + IDS_2152 "Cartridgeimages (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Alle Dateien (*.*)\0*.*\0" + IDS_2153 "Fehler bei der Rendererinitialisierung" + IDS_2154 "Der OpenGL (3.0-Kern)-Renderer konnte nicht initialisiert werden. Bitte benutzen Sie einen anderen Renderer." + IDS_2155 "Fortsetzen" + IDS_2156 "Pausieren" + IDS_2157 "Strg+Alt+Entf drücken" + IDS_2158 "Strg+Alt+Esc drücken" + IDS_2159 "Hard-Reset" + IDS_2160 "ACPI-basiertes Herunterfahren" + IDS_2161 "Optionen" + IDS_2162 "Früheres Laufwerk" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/dialogs.rc b/src/win/languages/dialogs.rc index 3f3811c25..d32192397 100644 --- a/src/win/languages/dialogs.rc +++ b/src/win/languages/dialogs.rc @@ -260,21 +260,29 @@ BEGIN PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_VID, CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT + LTEXT STR_VIDEO_2, IDT_VIDEO_2, + CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT + COMBOBOX IDC_COMBO_VIDEO_2, + CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, + CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_VID_2, + CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT + CONTROL STR_VOODOO, IDC_CHECK_VOODOO, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 7, 27, 199, CFG_CHECKBOX_HEIGHT + CFG_HMARGIN, 47, 199, CFG_CHECKBOX_HEIGHT PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_VOODOO, - CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT + CFG_COMBO_BTN_LEFT, 45, CFG_BTN_WIDTH, CFG_BTN_HEIGHT CONTROL STR_IBM8514, IDC_CHECK_IBM8514, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 7, 46, 199, CFG_CHECKBOX_HEIGHT + CFG_HMARGIN, 66, 199, CFG_CHECKBOX_HEIGHT CONTROL STR_XGA, IDC_CHECK_XGA, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 7, 65, 199, CFG_CHECKBOX_HEIGHT + CFG_HMARGIN, 85, 199, CFG_CHECKBOX_HEIGHT PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_XGA, - CFG_COMBO_BTN_LEFT, 64, CFG_BTN_WIDTH, CFG_BTN_HEIGHT + CFG_COMBO_BTN_LEFT, 84, CFG_BTN_WIDTH, CFG_BTN_HEIGHT END DLG_CFG_INPUT DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT @@ -938,6 +946,7 @@ END #undef STR_DYNAREC #undef STR_VIDEO +#undef STR_VIDEO_2 #undef STR_VOODOO #undef STR_IBM8514 #undef STR_XGA diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index 0321e6dea..dc0ec3627 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Hide status bar", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Resizeable window", IDM_VID_RESIZE MENUITEM "R&emember size && position", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_EMPTY MENUITEM "&Reload previous image", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image", IDM_CDROM_IMAGE - MENUITEM "&Folder", IDM_CDROM_DIR + MENUITEM "&Image...", IDM_CDROM_IMAGE + MENUITEM "&Folder...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Dynamic Recompiler" #define STR_VIDEO "Video:" +#define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo Graphics" #define STR_IBM8514 "IBM 8514/a Graphics" #define STR_XGA "XGA Graphics" @@ -333,6 +335,7 @@ END #define STR_BUS "Bus:" #define STR_CHANNEL "Channel:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Specify..." #define STR_SECTORS "Sectors:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Check BPB" - IDS_2088 "KB" - IDS_2089 "Could not initialize the video renderer." - IDS_2090 "Default" - IDS_2091 "%i Wait state(s)" - IDS_2092 "Type" - IDS_2093 "Failed to set up PCap" - IDS_2094 "No PCap devices found" - IDS_2095 "Invalid PCap device" - IDS_2096 "Standard 2-button joystick(s)" - IDS_2097 "Standard 4-button joystick" - IDS_2098 "Standard 6-button joystick" - IDS_2099 "Standard 8-button joystick" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "None" - IDS_2104 "Unable to load keyboard accelerators." - IDS_2105 "Unable to register raw input." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Floppy %i (%s): %ls" - IDS_2109 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2110 "Unable to initialize FreeType" - IDS_2111 "Unable to initialize SDL, SDL2.dll is required" - IDS_2112 "Are you sure you want to hard reset the emulated machine?" - IDS_2113 "Are you sure you want to exit 86Box?" - IDS_2114 "Unable to initialize Ghostscript" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2117 "Welcome to 86Box!" - IDS_2118 "Internal controller" - IDS_2119 "Exit" - IDS_2120 "No ROMs found" - IDS_2121 "Do you want to save the settings?" - IDS_2122 "This will hard reset the emulated machine." - IDS_2123 "Save" - IDS_2124 "About 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Check BPB" + IDS_2089 "KB" + IDS_2090 "Could not initialize the video renderer." + IDS_2091 "Default" + IDS_2092 "%i Wait state(s)" + IDS_2093 "Type" + IDS_2094 "Failed to set up PCap" + IDS_2095 "No PCap devices found" + IDS_2096 "Invalid PCap device" + IDS_2097 "Standard 2-button joystick(s)" + IDS_2098 "Standard 4-button joystick" + IDS_2099 "Standard 6-button joystick" + IDS_2100 "Standard 8-button joystick" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "None" + IDS_2105 "Unable to load keyboard accelerators." + IDS_2106 "Unable to register raw input." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Floppy %i (%s): %ls" + IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" + IDS_2111 "Unable to initialize FreeType" + IDS_2112 "Unable to initialize SDL, SDL2.dll is required" + IDS_2113 "Are you sure you want to hard reset the emulated machine?" + IDS_2114 "Are you sure you want to exit 86Box?" + IDS_2115 "Unable to initialize Ghostscript" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" + IDS_2118 "Welcome to 86Box!" + IDS_2119 "Internal controller" + IDS_2120 "Exit" + IDS_2121 "No ROMs found" + IDS_2122 "Do you want to save the settings?" + IDS_2123 "This will hard reset the emulated machine." + IDS_2124 "Save" + IDS_2125 "About 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - IDS_2127 "OK" - IDS_2128 "Hardware not available" + IDS_2127 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." + IDS_2128 "OK" + IDS_2129 "Hardware not available" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." - IDS_2130 "Invalid configuration" + IDS_2130 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." + IDS_2131 "Invalid configuration" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " is required for ESC/P printer emulation." + IDS_2132 LIB_NAME_FREETYPE " is required for ESC/P printer emulation." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." + IDS_2133 LIB_NAME_GS " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " is required for FluidSynth MIDI output." - IDS_2134 "Entering fullscreen mode" - IDS_2135 "Don't show this message again" - IDS_2136 "Don't exit" - IDS_2137 "Reset" - IDS_2138 "Don't reset" - IDS_2139 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2140 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2141 "%hs Device Configuration" - IDS_2142 "Monitor in sleep mode" - IDS_2143 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2144 "OpenGL options" - IDS_2145 "You are loading an unsupported configuration" - IDS_2146 "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." - IDS_2147 "Continue" - IDS_2148 "Cassette: %s" - IDS_2149 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" - IDS_2150 "Cartridge %i: %ls" - IDS_2151 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" - IDS_2152 "Error initializing renderer" - IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2154 "Resume execution" - IDS_2155 "Pause execution" - IDS_2156 "Press Ctrl+Alt+Del" - IDS_2157 "Press Ctrl+Alt+Esc" - IDS_2158 "Hard reset" - IDS_2159 "ACPI shutdown" - IDS_2160 "Settings" - IDS_2161 "Earlier drive" + IDS_2134 LIB_NAME_FLUIDSYNTH " is required for FluidSynth MIDI output." + IDS_2135 "Entering fullscreen mode" + IDS_2136 "Don't show this message again" + IDS_2137 "Don't exit" + IDS_2138 "Reset" + IDS_2139 "Don't reset" + IDS_2140 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" + IDS_2141 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" + IDS_2142 "%hs Device Configuration" + IDS_2143 "Monitor in sleep mode" + IDS_2144 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" + IDS_2145 "OpenGL options" + IDS_2146 "You are loading an unsupported configuration" + IDS_2147 "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." + IDS_2148 "Continue" + IDS_2149 "Cassette: %s" + IDS_2150 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" + IDS_2151 "Cartridge %i: %ls" + IDS_2152 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" + IDS_2153 "Error initializing renderer" + IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + IDS_2155 "Resume execution" + IDS_2156 "Pause execution" + IDS_2157 "Press Ctrl+Alt+Del" + IDS_2158 "Press Ctrl+Alt+Esc" + IDS_2159 "Hard reset" + IDS_2160 "ACPI shutdown" + IDS_2161 "Settings" + IDS_2162 "Earlier drive" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index f061a061b..d166b1d0c 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Hide status bar", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Resizeable window", IDM_VID_RESIZE MENUITEM "R&emember size && position", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_EMPTY MENUITEM "&Reload previous image", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image", IDM_CDROM_IMAGE - MENUITEM "&Folder", IDM_CDROM_DIR + MENUITEM "&Image...", IDM_CDROM_IMAGE + MENUITEM "&Folder...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Dynamic Recompiler" #define STR_VIDEO "Video:" +#define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo Graphics" #define STR_IBM8514 "IBM 8514/a Graphics" #define STR_XGA "XGA Graphics" @@ -333,6 +335,7 @@ END #define STR_BUS "Bus:" #define STR_CHANNEL "Channel:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Specify..." #define STR_SECTORS "Sectors:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Check BPB" - IDS_2088 "KB" - IDS_2089 "Could not initialize the video renderer." - IDS_2090 "Default" - IDS_2091 "%i Wait state(s)" - IDS_2092 "Type" - IDS_2093 "Failed to set up PCap" - IDS_2094 "No PCap devices found" - IDS_2095 "Invalid PCap device" - IDS_2096 "Standard 2-button joystick(s)" - IDS_2097 "Standard 4-button joystick" - IDS_2098 "Standard 6-button joystick" - IDS_2099 "Standard 8-button joystick" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "None" - IDS_2104 "Unable to load keyboard accelerators." - IDS_2105 "Unable to register raw input." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Floppy %i (%s): %ls" - IDS_2109 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2110 "Unable to initialize FreeType" - IDS_2111 "Unable to initialize SDL, SDL2.dll is required" - IDS_2112 "Are you sure you want to hard reset the emulated machine?" - IDS_2113 "Are you sure you want to exit 86Box?" - IDS_2114 "Unable to initialize Ghostscript" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2117 "Welcome to 86Box!" - IDS_2118 "Internal controller" - IDS_2119 "Exit" - IDS_2120 "No ROMs found" - IDS_2121 "Do you want to save the settings?" - IDS_2122 "This will hard reset the emulated machine." - IDS_2123 "Save" - IDS_2124 "About 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Check BPB" + IDS_2089 "KB" + IDS_2090 "Could not initialize the video renderer." + IDS_2091 "Default" + IDS_2092 "%i Wait state(s)" + IDS_2093 "Type" + IDS_2094 "Failed to set up PCap" + IDS_2095 "No PCap devices found" + IDS_2096 "Invalid PCap device" + IDS_2097 "Standard 2-button joystick(s)" + IDS_2098 "Standard 4-button joystick" + IDS_2099 "Standard 6-button joystick" + IDS_2100 "Standard 8-button joystick" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "None" + IDS_2105 "Unable to load keyboard accelerators." + IDS_2106 "Unable to register raw input." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Floppy %i (%s): %ls" + IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" + IDS_2111 "Unable to initialize FreeType" + IDS_2112 "Unable to initialize SDL, SDL2.dll is required" + IDS_2113 "Are you sure you want to hard reset the emulated machine?" + IDS_2114 "Are you sure you want to exit 86Box?" + IDS_2115 "Unable to initialize Ghostscript" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" + IDS_2118 "Welcome to 86Box!" + IDS_2119 "Internal controller" + IDS_2120 "Exit" + IDS_2121 "No ROMs found" + IDS_2122 "Do you want to save the settings?" + IDS_2123 "This will hard reset the emulated machine." + IDS_2124 "Save" + IDS_2125 "About 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - IDS_2127 "OK" - IDS_2128 "Hardware not available" + IDS_2127 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." + IDS_2128 "OK" + IDS_2129 "Hardware not available" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." - IDS_2130 "Invalid configuration" + IDS_2130 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." + IDS_2131 "Invalid configuration" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " is required for ESC/P printer emulation." + IDS_2132 LIB_NAME_FREETYPE " is required for ESC/P printer emulation." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." + IDS_2133 LIB_NAME_GS " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " is required for FluidSynth MIDI output." - IDS_2134 "Entering fullscreen mode" - IDS_2135 "Don't show this message again" - IDS_2136 "Don't exit" - IDS_2137 "Reset" - IDS_2138 "Don't reset" - IDS_2139 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2140 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2141 "%hs Device Configuration" - IDS_2142 "Monitor in sleep mode" - IDS_2143 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2144 "OpenGL options" - IDS_2145 "You are loading an unsupported configuration" - IDS_2146 "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." - IDS_2147 "Continue" - IDS_2148 "Cassette: %s" - IDS_2149 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" - IDS_2150 "Cartridge %i: %ls" - IDS_2151 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" - IDS_2152 "Error initializing renderer" - IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2154 "Resume execution" - IDS_2155 "Pause execution" - IDS_2156 "Press Ctrl+Alt+Del" - IDS_2157 "Press Ctrl+Alt+Esc" - IDS_2158 "Hard reset" - IDS_2159 "ACPI shutdown" - IDS_2160 "Settings" - IDS_2161 "Earlier drive" + IDS_2134 LIB_NAME_FLUIDSYNTH " is required for FluidSynth MIDI output." + IDS_2135 "Entering fullscreen mode" + IDS_2136 "Don't show this message again" + IDS_2137 "Don't exit" + IDS_2138 "Reset" + IDS_2139 "Don't reset" + IDS_2140 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" + IDS_2141 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" + IDS_2142 "%hs Device Configuration" + IDS_2143 "Monitor in sleep mode" + IDS_2144 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" + IDS_2145 "OpenGL options" + IDS_2146 "You are loading an unsupported configuration" + IDS_2147 "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." + IDS_2148 "Continue" + IDS_2149 "Cassette: %s" + IDS_2150 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" + IDS_2151 "Cartridge %i: %ls" + IDS_2152 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" + IDS_2153 "Error initializing renderer" + IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + IDS_2155 "Resume execution" + IDS_2156 "Pause execution" + IDS_2157 "Press Ctrl+Alt+Del" + IDS_2158 "Press Ctrl+Alt+Esc" + IDS_2159 "Hard reset" + IDS_2160 "ACPI shutdown" + IDS_2161 "Settings" + IDS_2162 "Earlier drive" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc index 893759d62..faba0638c 100644 --- a/src/win/languages/es-ES.rc +++ b/src/win/languages/es-ES.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Ventana redimensionable", IDM_VID_RESIZE MENUITEM "&Recordar tamaño y posición", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -177,7 +178,7 @@ BEGIN MENUITEM "&Recargar imagen previa", IDM_CDROM_RELOAD MENUITEM SEPARATOR MENUITEM "&Imagen...", IDM_CDROM_IMAGE - MENUITEM "&Carpeta", IDM_CDROM_DIR + MENUITEM "&Carpeta...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Recompilador Dinámico" #define STR_VIDEO "Vídeo:" +#define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "Voodoo Graphics" #define STR_IBM8514 "IBM 8514/a Graphics" #define STR_XGA "XGA Graphics" @@ -333,6 +335,7 @@ END #define STR_BUS "Bus:" #define STR_CHANNEL "Canal:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "E&specificar..." #define STR_SECTORS "Sectores:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Chequear BPB" - IDS_2088 "KB" - IDS_2089 "Incapaz de inicializar el renderizador de vídeo." - IDS_2090 "Por defecto" - IDS_2091 "%i estado(s) de Espera" - IDS_2092 "Tipo" - IDS_2093 "Incapaz de configurar PCap" - IDS_2094 "No se encontraron dispositivos PCap" - IDS_2095 "Dispositivo PCap inválido" - IDS_2096 "Mando(s) de 2 botones estándar" - IDS_2097 "Mando de 4 botones estándar" - IDS_2098 "Mando de 6 botones estándar" - IDS_2099 "Mando de 8 botones estándar" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Ninguno" - IDS_2104 "Incapaz de cargar aceleradores de teclado." - IDS_2105 "Incapaz de registrar entrada directa." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Disquete %i (%s): %ls" - IDS_2109 "Todas las Imágenes (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2110 "Incapaz de inicializar FreeType" - IDS_2111 "Incapaz de inicializar SDL, se requiere SDL2.dll" - IDS_2112 "¿Seguro que quieres resetear la máquina emulada?" - IDS_2113 "¿Seguro que quieres cerrar 86Box?" - IDS_2114 "Incapaz de inicializar Ghostscript" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "Imágenes de MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2117 "¡Bienvenido a 86Box!" - IDS_2118 "Controladora interna" - IDS_2119 "Salir" - IDS_2120 "No se encontraron ROMs" - IDS_2121 "¿Quieres guardar los ajustes?" - IDS_2122 "Se hará hard reset de la máquina emulada." - IDS_2123 "Guardar" - IDS_2124 "Acerca de 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Chequear BPB" + IDS_2089 "KB" + IDS_2090 "Incapaz de inicializar el renderizador de vídeo." + IDS_2091 "Por defecto" + IDS_2092 "%i estado(s) de Espera" + IDS_2093 "Tipo" + IDS_2094 "Incapaz de configurar PCap" + IDS_2095 "No se encontraron dispositivos PCap" + IDS_2096 "Dispositivo PCap inválido" + IDS_2097 "Mando(s) de 2 botones estándar" + IDS_2098 "Mando de 4 botones estándar" + IDS_2099 "Mando de 6 botones estándar" + IDS_2100 "Mando de 8 botones estándar" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Ninguno" + IDS_2105 "Incapaz de cargar aceleradores de teclado." + IDS_2106 "Incapaz de registrar entrada directa." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Disquete %i (%s): %ls" + IDS_2110 "Todas las Imágenes (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" + IDS_2111 "Incapaz de inicializar FreeType" + IDS_2112 "Incapaz de inicializar SDL, se requiere SDL2.dll" + IDS_2113 "¿Seguro que quieres resetear la máquina emulada?" + IDS_2114 "¿Seguro que quieres cerrar 86Box?" + IDS_2115 "Incapaz de inicializar Ghostscript" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "Imágenes de MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" + IDS_2118 "¡Bienvenido a 86Box!" + IDS_2119 "Controladora interna" + IDS_2120 "Salir" + IDS_2121 "No se encontraron ROMs" + IDS_2122 "¿Quieres guardar los ajustes?" + IDS_2123 "Se hará hard reset de la máquina emulada." + IDS_2124 "Guardar" + IDS_2125 "Acerca de 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "Un emulador de ordenadores antigüos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." - IDS_2127 "Aceptar" - IDS_2128 "Hardware no disponible" + IDS_2127 "Un emulador de ordenadores antigüos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." + IDS_2128 "Aceptar" + IDS_2129 "Hardware no disponible" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Asegúrate de que " LIB_NAME_PCAP " está instalado y de que estás en una conexión de red compatible con " LIB_NAME_PCAP "." - IDS_2130 "Configuración inválida" + IDS_2130 "Asegúrate de que " LIB_NAME_PCAP " está instalado y de que estás en una conexión de red compatible con " LIB_NAME_PCAP "." + IDS_2131 "Configuración inválida" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " es necesaria para emulación de impresión ESC/P." + IDS_2132 LIB_NAME_FREETYPE " es necesaria para emulación de impresión ESC/P." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." + IDS_2133 LIB_NAME_GS " es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " es necesario para salida MIDI FluidSynth." - IDS_2134 "Entrando en modo pantalla completa" - IDS_2135 "No mostrar más este mensaje" - IDS_2136 "No salir" - IDS_2137 "Resetear" - IDS_2138 "No resetear" - IDS_2139 "Imágenes de MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2140 "Imágenes de CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2141 "%hs Configuración de Dispositivo" - IDS_2142 "Monitor en modo ahorro" - IDS_2143 "Shaders OpenGL (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2144 "Opciones OpenGL" - IDS_2145 "Estás cargando una configuración no soportada" - IDS_2146 "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar este ajuste no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido." - IDS_2147 "Continuar" - IDS_2148 "Cassette: %s" - IDS_2149 "Imágenes de Cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" - IDS_2150 "Cartucho %i: %ls" - IDS_2151 "Imágenes de Cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" - IDS_2152 "Error initializing renderer" - IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2154 "Resume execution" - IDS_2155 "Pause execution" - IDS_2156 "Press Ctrl+Alt+Del" - IDS_2157 "Press Ctrl+Alt+Esc" - IDS_2158 "Hard reset" - IDS_2159 "ACPI shutdown" - IDS_2160 "Settings" - IDS_2161 "Unidad anterior" + IDS_2134 LIB_NAME_FLUIDSYNTH " es necesario para salida MIDI FluidSynth." + IDS_2135 "Entrando en modo pantalla completa" + IDS_2136 "No mostrar más este mensaje" + IDS_2137 "No salir" + IDS_2138 "Resetear" + IDS_2139 "No resetear" + IDS_2140 "Imágenes de MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" + IDS_2141 "Imágenes de CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" + IDS_2142 "%hs Configuración de Dispositivo" + IDS_2143 "Monitor en modo ahorro" + IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" + IDS_2145 "Opciones OpenGL" + IDS_2146 "Estás cargando una configuración no soportada" + IDS_2147 "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar este ajuste no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido." + IDS_2148 "Continuar" + IDS_2149 "Cassette: %s" + IDS_2150 "Imágenes de Cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" + IDS_2151 "Cartucho %i: %ls" + IDS_2152 "Imágenes de Cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" + IDS_2153 "Error initializing renderer" + IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + IDS_2155 "Resume execution" + IDS_2156 "Pause execution" + IDS_2157 "Press Ctrl+Alt+Del" + IDS_2158 "Press Ctrl+Alt+Esc" + IDS_2159 "Hard reset" + IDS_2160 "ACPI shutdown" + IDS_2161 "Settings" + IDS_2162 "Unidad anterior" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc index ccf1a5940..127508bdd 100644 --- a/src/win/languages/fi-FI.rc +++ b/src/win/languages/fi-FI.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Piilota tilapalkki", IDM_VID_HIDE_STATUS_BAR MENUITEM "Piilota &työkalupalkki", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Salli koon muuttaminen", IDM_VID_RESIZE MENUITEM "&Muista koko ja sijainti", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "&Tyhjä", IDM_CDROM_EMPTY MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "L&evykuva", IDM_CDROM_IMAGE - MENUITEM "&Kansio", IDM_CDROM_DIR + MENUITEM "L&evykuva...", IDM_CDROM_IMAGE + MENUITEM "&Kansio...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Dynaaminen uudelleenkääntäjä" #define STR_VIDEO "Näytönohjain:" +#define STR_VIDEO_2 "Näytönohjain 2:" #define STR_VOODOO "Voodoo-grafiikkasuoritin" #define STR_IBM8514 "IBM 8514/a-grafiikkasuoritin" #define STR_XGA "XGA-grafiikkasuoritin" @@ -333,6 +335,7 @@ END #define STR_BUS "Väylä:" #define STR_CHANNEL "Kanava:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Määritä..." #define STR_SECTORS "Sektorit:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "Mt" - IDS_2087 "Tarkista BPB" - IDS_2088 "kt" - IDS_2089 "Videorenderöijän alustus epäonnistui" - IDS_2090 "Oletus" - IDS_2091 "%i odotustilaa" - IDS_2092 "Tyyppi" - IDS_2093 "PCap-asennus epäonnistui" - IDS_2094 "PCap-laitteita ei löytynyt" - IDS_2095 "Virheellinen PCap-laite" - IDS_2096 "Standardi 2-painikkeinen peliohjain/-ohjaimet" - IDS_2097 "Standardi 4-painikkeinen peliohjain" - IDS_2098 "Standardi 6-painikkeinen peliohjain" - IDS_2099 "Standardi 8-painikkeinen peliohjain" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Ei mikään" - IDS_2104 "Näppäinkiihdyttimien lataus epäonnistui" - IDS_2105 "Raakasyötteen rekisteröinti epäonnistui" - IDS_2106 "%u" - IDS_2107 "%u Mt (CHS: %i, %i, %i)" - IDS_2108 "Levyke %i (%s): %ls" - IDS_2109 "Kaikki levykuvat (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Kehittyneet sektorilevykuvat (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Perussektorilevykuvat (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux-levykuvat (*.FDI)\0*.FDI\0Pintalevykuvat (*.86F;*.MFM)\0*.86F;*.MFM\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2110 "FreeType:n alustus epäonnistui" - IDS_2111 "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll" - IDS_2112 "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" - IDS_2113 "Haluatko varmasti sulkea 86Boxin?" - IDS_2114 "Ghostscriptin alustus epäonnistui" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "MO-levykuvat (*.IM?;*.MDI)\0*.IM?;*.MDI\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2117 "Tervetuloa 86Boxiin!" - IDS_2118 "Sisäinen ohjain" - IDS_2119 "Poistu" - IDS_2120 "ROM-tiedostoja ei löytynyt" - IDS_2121 "Tallennetaanko asetukset?" - IDS_2122 "Tämä käynnistää emuloidun tietokoneen uudelleen." - IDS_2123 "Tallenna" - IDS_2124 "Tietoja 86Box:sta" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Tarkista BPB" + IDS_2089 "kt" + IDS_2090 "Videorenderöijän alustus epäonnistui" + IDS_2091 "Oletus" + IDS_2092 "%i odotustilaa" + IDS_2093 "Tyyppi" + IDS_2094 "PCap-asennus epäonnistui" + IDS_2095 "PCap-laitteita ei löytynyt" + IDS_2096 "Virheellinen PCap-laite" + IDS_2097 "Standardi 2-painikkeinen peliohjain/-ohjaimet" + IDS_2098 "Standardi 4-painikkeinen peliohjain" + IDS_2099 "Standardi 6-painikkeinen peliohjain" + IDS_2100 "Standardi 8-painikkeinen peliohjain" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Ei mikään" + IDS_2105 "Näppäinkiihdyttimien lataus epäonnistui" + IDS_2106 "Raakasyötteen rekisteröinti epäonnistui" + IDS_2107 "%u" + IDS_2108 "%u Mt (CHS: %i, %i, %i)" + IDS_2109 "Levyke %i (%s): %ls" + IDS_2110 "Kaikki levykuvat (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Kehittyneet sektorilevykuvat (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Perussektorilevykuvat (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux-levykuvat (*.FDI)\0*.FDI\0Pintalevykuvat (*.86F;*.MFM)\0*.86F;*.MFM\0Kaikki tiedostot (*.*)\0*.*\0" + IDS_2111 "FreeType:n alustus epäonnistui" + IDS_2112 "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll" + IDS_2113 "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" + IDS_2114 "Haluatko varmasti sulkea 86Boxin?" + IDS_2115 "Ghostscriptin alustus epäonnistui" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "MO-levykuvat (*.IM?;*.MDI)\0*.IM?;*.MDI\0Kaikki tiedostot (*.*)\0*.*\0" + IDS_2118 "Tervetuloa 86Boxiin!" + IDS_2119 "Sisäinen ohjain" + IDS_2120 "Poistu" + IDS_2121 "ROM-tiedostoja ei löytynyt" + IDS_2122 "Tallennetaanko asetukset?" + IDS_2123 "Tämä käynnistää emuloidun tietokoneen uudelleen." + IDS_2124 "Tallenna" + IDS_2125 "Tietoja 86Box:sta" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "Vanhojen tietokoneiden emulaattori\n\nTekijät: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." - IDS_2127 "OK" - IDS_2128 "Laitteisto ei ole saatavilla" + IDS_2127 "Vanhojen tietokoneiden emulaattori\n\nTekijät: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." + IDS_2128 "OK" + IDS_2129 "Laitteisto ei ole saatavilla" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Varmista, että " LIB_NAME_PCAP " on asennettu ja että verkkoyhteytesi on " LIB_NAME_PCAP "-yhteensopiva." - IDS_2130 "Virheelliset määritykset" + IDS_2130 "Varmista, että " LIB_NAME_PCAP " on asennettu ja että verkkoyhteytesi on " LIB_NAME_PCAP "-yhteensopiva." + IDS_2131 "Virheelliset määritykset" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " vaaditaan ESC/P-tulostimen emuloimiseksi." + IDS_2132 LIB_NAME_FREETYPE " vaaditaan ESC/P-tulostimen emuloimiseksi." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." + IDS_2133 LIB_NAME_GS " vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " vaaditaan FluidSynth MIDI-ulostuloa varten." - IDS_2134 "Siirrytään koko näytön tilaan" - IDS_2135 "Älä näytä tätä viestiä uudelleen" - IDS_2136 "Älä poistu" - IDS_2137 "Käynnistä uudelleen" - IDS_2138 "Älä käynnistä uudelleen" - IDS_2139 "MO-levykuvat (*.IM?;*.MDI)\0*.IM?;*.MDI\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2140 "CD-ROM-levykuvat (*.ISO;*.CUE)\0*.ISO;*.CUE\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2141 "%hs - Laitteen määritykset" - IDS_2142 "Näyttö lepotilassa" - IDS_2143 "OpenGL-varjostinohjelmat (*.GLSL)\0*.GLSL\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2144 "OpenGL-asetukset" - IDS_2145 "Olet lataamassa ei-tuettuja määrittelyjä" - IDS_2146 "Valittuun tietokoneeseen perustuva suoritintyypin suodatus ei ole käytössä tällä emuloidulla koneella.\n\nTämä mahdollistaa muutoin yhteensopimattoman suorittimen valinnan kyseisen tietokoneen kanssa. Voit kuitenkin kohdata ongelmia tietokoneen BIOS:in tai muun ohjelmiston kanssa.\n\nTämän asetuksen käyttö ei ole virallisesti tuettua ja kaikki tehdyt virheraportit voidaan sulkea epäpätevinä." - IDS_2147 "Jatka" - IDS_2148 "Kasetti: %s" - IDS_2149 "Kasettitiedostot (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2150 "ROM-moduuli %i: %ls" - IDS_2151 "ROM-moduulikuvat (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2152 "Virhe renderöijän alustuksessa" - IDS_2153 "OpenGL (3.0 Core) -renderöijän alustus epäonnistui. Käytä toista renderöijää." - IDS_2154 "Jatka suoritusta" - IDS_2155 "Pysäytä suoritus" - IDS_2156 "Paina Ctrl+Alt+Del" - IDS_2157 "Paina Ctrl+Alt+Esc" - IDS_2158 "Kylmä uudelleenkäynnistys" - IDS_2159 "ACPI-sammutus" - IDS_2160 "Asetukset" - IDS_2161 "Aiemmat asemat" + IDS_2134 LIB_NAME_FLUIDSYNTH " vaaditaan FluidSynth MIDI-ulostuloa varten." + IDS_2135 "Siirrytään koko näytön tilaan" + IDS_2136 "Älä näytä tätä viestiä uudelleen" + IDS_2137 "Älä poistu" + IDS_2138 "Käynnistä uudelleen" + IDS_2139 "Älä käynnistä uudelleen" + IDS_2140 "MO-levykuvat (*.IM?;*.MDI)\0*.IM?;*.MDI\0Kaikki tiedostot (*.*)\0*.*\0" + IDS_2141 "CD-ROM-levykuvat (*.ISO;*.CUE)\0*.ISO;*.CUE\0Kaikki tiedostot (*.*)\0*.*\0" + IDS_2142 "%hs - Laitteen määritykset" + IDS_2143 "Näyttö lepotilassa" + IDS_2144 "OpenGL-varjostinohjelmat (*.GLSL)\0*.GLSL\0Kaikki tiedostot (*.*)\0*.*\0" + IDS_2145 "OpenGL-asetukset" + IDS_2146 "Olet lataamassa ei-tuettuja määrittelyjä" + IDS_2147 "Valittuun tietokoneeseen perustuva suoritintyypin suodatus ei ole käytössä tällä emuloidulla koneella.\n\nTämä mahdollistaa muutoin yhteensopimattoman suorittimen valinnan kyseisen tietokoneen kanssa. Voit kuitenkin kohdata ongelmia tietokoneen BIOS:in tai muun ohjelmiston kanssa.\n\nTämän asetuksen käyttö ei ole virallisesti tuettua ja kaikki tehdyt virheraportit voidaan sulkea epäpätevinä." + IDS_2148 "Jatka" + IDS_2149 "Kasetti: %s" + IDS_2150 "Kasettitiedostot (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Kaikki tiedostot (*.*)\0*.*\0" + IDS_2151 "ROM-moduuli %i: %ls" + IDS_2152 "ROM-moduulikuvat (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Kaikki tiedostot (*.*)\0*.*\0" + IDS_2153 "Virhe renderöijän alustuksessa" + IDS_2154 "OpenGL (3.0 Core) -renderöijän alustus epäonnistui. Käytä toista renderöijää." + IDS_2155 "Jatka suoritusta" + IDS_2156 "Pysäytä suoritus" + IDS_2157 "Paina Ctrl+Alt+Del" + IDS_2158 "Paina Ctrl+Alt+Esc" + IDS_2159 "Kylmä uudelleenkäynnistys" + IDS_2160 "ACPI-sammutus" + IDS_2161 "Asetukset" + IDS_2162 "Aiemmat asemat" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index 858a2dacf..c7cdf65d7 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Masquer la barre de status", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "Fenètre &Retaillable", IDM_VID_RESIZE MENUITEM "S&auvegarder taille && position", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "E&jecter", IDM_CDROM_EMPTY MENUITEM "&Recharger image précedente", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image", IDM_CDROM_IMAGE - MENUITEM "&Dossier", IDM_CDROM_DIR + MENUITEM "&Image...", IDM_CDROM_IMAGE + MENUITEM "&Dossier...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Recompilateur dynamique" #define STR_VIDEO "Vidéo:" +#define STR_VIDEO_2 "Vidéo 2:" #define STR_VOODOO "Graphique Voodoo" #define STR_IBM8514 "Graphique IBM 8514/a" #define STR_XGA "Graphique XGA" @@ -333,6 +335,7 @@ END #define STR_BUS "Bus:" #define STR_CHANNEL "Canal:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Spécifier..." #define STR_SECTORS "Secteurs:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "T" IDS_2085 "S" IDS_2086 "Mo" - IDS_2087 "Vérifier BPB" - IDS_2088 "Ko" - IDS_2089 "Impossible d'initialiser le moteur de rendu vidéo." - IDS_2090 "Défaut" - IDS_2091 "%i état(s) d'attente" - IDS_2092 "Type" - IDS_2093 "Impossible d'initialiser PCap" - IDS_2094 "Aucun dispositif PCap trouvé" - IDS_2095 "Dispositif PCap non valide" - IDS_2096 "Manette(s) standard avec 2 boutons" - IDS_2097 "Manette standard avec 4 boutons" - IDS_2098 "Manette standard avec 6 boutons" + IDS_2087 "Speed" + IDS_2088 "Vérifier BPB" + IDS_2089 "Ko" + IDS_2090 "Impossible d'initialiser le moteur de rendu vidéo." + IDS_2091 "Défaut" + IDS_2092 "%i état(s) d'attente" + IDS_2093 "Type" + IDS_2094 "Impossible d'initialiser PCap" + IDS_2095 "Aucun dispositif PCap trouvé" + IDS_2096 "Dispositif PCap non valide" + IDS_2097 "Manette(s) standard avec 2 boutons" + IDS_2098 "Manette standard avec 4 boutons" IDS_2099 "Manette standard avec 6 boutons" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Système de contrôle de vol Thrustmaster" - IDS_2103 "Aucun" - IDS_2104 "Impossible de charger les accélérateurs de clavier." - IDS_2105 "Impossible de charger l'entrée raw." - IDS_2106 "%u" - IDS_2107 "%u Mo (CTS: %i, %i, %i)" - IDS_2108 "Disquette %i (%s): %ls" - IDS_2109 "Toutes les images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Images du secteur avancés (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Images du secteur basiques (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Images du flux (*.FDI)\0*.FDI\0Images de surface (*.86F;*.MFM)\0*.86F;*.MFM\0Tous les fichiers (*.*)\0*.*\0" - IDS_2110 "Impossible d'initialiser FreeType" - IDS_2111 "Impossible d'initialiser SDL, SDL2.dll est nécessaire" - IDS_2112 "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" - IDS_2113 "Etes-vous sûr de vouloir quitter 86Box?" - IDS_2114 "Impossible d'initialiser Ghostscript" - IDS_2115 "Magnéto-optique %i (%ls): %ls" - IDS_2116 "Images magnéto-optiques (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tous les fichiers (*.*)\0*.*\0" - IDS_2117 "Bienvenue dans 86Box !" - IDS_2118 "Côntrolleur interne" - IDS_2119 "Sortir" - IDS_2120 "Pas de ROMs trouvées" - IDS_2121 "Voulez-vous sauvegarder les paramètres ?" - IDS_2122 "Cela entraînera la réinitialisation complète de la machine émulée." - IDS_2123 "Sauvegarder" - IDS_2124 "À propos de 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2100 "Manette standard avec 6 boutons" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Système de contrôle de vol Thrustmaster" + IDS_2104 "Aucun" + IDS_2105 "Impossible de charger les accélérateurs de clavier." + IDS_2106 "Impossible de charger l'entrée raw." + IDS_2107 "%u" + IDS_2108 "%u Mo (CTS: %i, %i, %i)" + IDS_2109 "Disquette %i (%s): %ls" + IDS_2110 "Toutes les images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Images du secteur avancés (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Images du secteur basiques (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Images du flux (*.FDI)\0*.FDI\0Images de surface (*.86F;*.MFM)\0*.86F;*.MFM\0Tous les fichiers (*.*)\0*.*\0" + IDS_2111 "Impossible d'initialiser FreeType" + IDS_2112 "Impossible d'initialiser SDL, SDL2.dll est nécessaire" + IDS_2113 "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" + IDS_2114 "Etes-vous sûr de vouloir quitter 86Box?" + IDS_2115 "Impossible d'initialiser Ghostscript" + IDS_2116 "Magnéto-optique %i (%ls): %ls" + IDS_2117 "Images magnéto-optiques (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tous les fichiers (*.*)\0*.*\0" + IDS_2118 "Bienvenue dans 86Box !" + IDS_2119 "Côntrolleur interne" + IDS_2120 "Sortir" + IDS_2121 "Pas de ROMs trouvées" + IDS_2122 "Voulez-vous sauvegarder les paramètres ?" + IDS_2123 "Cela entraînera la réinitialisation complète de la machine émulée." + IDS_2124 "Sauvegarder" + IDS_2125 "À propos de 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "Un émulateur de vieux ordinateurs\n\nAuteurs: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." - IDS_2127 "OK" - IDS_2128 "Matériel non disponible" + IDS_2127 "Un émulateur de vieux ordinateurs\n\nAuteurs: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." + IDS_2128 "OK" + IDS_2129 "Matériel non disponible" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Assurez-vous que " LIB_NAME_PCAP " est installé et que vou utilisez une connexion réseau compatible avec " LIB_NAME_PCAP "." - IDS_2130 "Configuration non valide" + IDS_2130 "Assurez-vous que " LIB_NAME_PCAP " est installé et que vou utilisez une connexion réseau compatible avec " LIB_NAME_PCAP "." + IDS_2131 "Configuration non valide" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " est nécessaire pour l'émulation de l'imprimante ESC/P." + IDS_2132 LIB_NAME_FREETYPE " est nécessaire pour l'émulation de l'imprimante ESC/P." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." + IDS_2133 LIB_NAME_GS " est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " est nécessaire pour la sortie MIDI FluidSynth." - IDS_2134 "Entrer en mode plein écran" - IDS_2135 "Ne pas montrer ce message à nouveau" - IDS_2136 "Ne pas sortir" - IDS_2137 "Réinitialiser" - IDS_2138 "Ne pas réinitialiser" - IDS_2139 "Images magnéto-optiques (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tous les fichiers (*.*)\0*.*\0" - IDS_2140 "Images CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tous les fichiers (*.*)\0*.*\0" - IDS_2141 "Configuration du dispositif %hs" - IDS_2142 "Moniteur en mode veille" - IDS_2143 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Tous les fichiers (*.*)\0*.*\0" - IDS_2144 "Options OpenGL" - IDS_2145 "Vous chargez une configuration non prise en charge" - IDS_2146 "La filtrage du type du processeur sur la base de la machine sélectionné est désactivé pur cette machine émulée.\n\nCela permet de sélectionner une processeur que est sinon incompatible avec la machine sélectionné. Cependant, il pourrait y avoir des incompatibilités avec le BIOS de la machine ou autres logiciels.\n\nL'activatione de cette configuration non est officiellement prise en charge et tout rapport de bogue peut être fermé comme étant invalide." - IDS_2147 "Continuer" - IDS_2148 "Cassette: %s" - IDS_2149 "Images cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tous les fichiers (*.*)\0*.*\0" - IDS_2150 "Cartouche %i: %ls" - IDS_2151 "Images cartouche (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tous les fichiers (*.*)\0*.*\0" - IDS_2152 "Error initializing renderer" - IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2154 "Resume execution" - IDS_2155 "Pause execution" - IDS_2156 "Press Ctrl+Alt+Del" - IDS_2157 "Press Ctrl+Alt+Esc" - IDS_2158 "Hard reset" - IDS_2159 "ACPI shutdown" - IDS_2160 "Settings" - IDS_2161 "Lecteur plus tôt" + IDS_2134 LIB_NAME_FLUIDSYNTH " est nécessaire pour la sortie MIDI FluidSynth." + IDS_2135 "Entrer en mode plein écran" + IDS_2136 "Ne pas montrer ce message à nouveau" + IDS_2137 "Ne pas sortir" + IDS_2138 "Réinitialiser" + IDS_2139 "Ne pas réinitialiser" + IDS_2140 "Images magnéto-optiques (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tous les fichiers (*.*)\0*.*\0" + IDS_2141 "Images CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tous les fichiers (*.*)\0*.*\0" + IDS_2142 "Configuration du dispositif %hs" + IDS_2143 "Moniteur en mode veille" + IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Tous les fichiers (*.*)\0*.*\0" + IDS_2145 "Options OpenGL" + IDS_2146 "Vous chargez une configuration non prise en charge" + IDS_2147 "La filtrage du type du processeur sur la base de la machine sélectionné est désactivé pur cette machine émulée.\n\nCela permet de sélectionner une processeur que est sinon incompatible avec la machine sélectionné. Cependant, il pourrait y avoir des incompatibilités avec le BIOS de la machine ou autres logiciels.\n\nL'activatione de cette configuration non est officiellement prise en charge et tout rapport de bogue peut être fermé comme étant invalide." + IDS_2148 "Continuer" + IDS_2149 "Cassette: %s" + IDS_2150 "Images cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tous les fichiers (*.*)\0*.*\0" + IDS_2151 "Cartouche %i: %ls" + IDS_2152 "Images cartouche (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tous les fichiers (*.*)\0*.*\0" + IDS_2153 "Error initializing renderer" + IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + IDS_2155 "Resume execution" + IDS_2156 "Pause execution" + IDS_2157 "Press Ctrl+Alt+Del" + IDS_2158 "Press Ctrl+Alt+Esc" + IDS_2159 "Hard reset" + IDS_2160 "ACPI shutdown" + IDS_2161 "Settings" + IDS_2162 "Lecteur plus tôt" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc index fcd4f9293..f2952bbcf 100644 --- a/src/win/languages/hr-HR.rc +++ b/src/win/languages/hr-HR.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Sakrij statusni redak", IDM_VID_HIDE_STATUS_BAR MENUITEM "&Sakrij alatni redak", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Prozor s promjenjivim veličinama", IDM_VID_RESIZE MENUITEM "&Zapamtite veličinu i položaj", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "&Prazno", IDM_CDROM_EMPTY MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Slika", IDM_CDROM_IMAGE - MENUITEM "&Mapa", IDM_CDROM_DIR + MENUITEM "&Slika...", IDM_CDROM_IMAGE + MENUITEM "&Mapa...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Dinamički rekompilator" #define STR_VIDEO "Video:" +#define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo grafika" #define STR_IBM8514 "IBM 8514/a grafika" #define STR_XGA "XGA grafika" @@ -333,6 +335,7 @@ END #define STR_BUS "Sabirnica:" #define STR_CHANNEL "Kanal:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Odredi..." #define STR_SECTORS "Sektori:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Provjeri BPB" - IDS_2088 "KB" - IDS_2089 "Nije moguće inicijalizirati renderer." - IDS_2090 "Standard" - IDS_2091 "%i stanje čekanja" - IDS_2092 "Tip" - IDS_2093 "Postavljanje PCap-a nije uspjelo" - IDS_2094 "Nema PCap uređaja" - IDS_2095 "Nevažeći PCap uređaj" - IDS_2096 "Standardna palica za igru s 2 tipke" - IDS_2097 "Standardna palica za igru s 4 tipke" - IDS_2098 "Standardna palica za igru s 6 tipke" - IDS_2099 "Standardna palica za igru s 8 tipke" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Bez" - IDS_2104 "Nije moguće učitati ubrzivače tipkovnice." - IDS_2105 "Nije moguće registrirati neobrađeni unos." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Disketa %i (%s): %ls" - IDS_2109 "Sve slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Sve datoteke (*.*)\0*.*\0" - IDS_2110 "Nije moguće inicijalizirati FreeType" - IDS_2111 "Nije moguće inicijalizirati SDL, SDL2.dll je potrebno" - IDS_2112 "Jeste li sigurni da želite hard resetirati emulirani sistem?" - IDS_2113 "Jeste li sigurni da želite zatvoriti 86Box?" - IDS_2114 "Nije moguće inicijalizirati GhostScript" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "MO slike (*.IM?;*.MDI)\0*.IM?;*.MDI\0Svi datoteke (*.*)\0*.*\0" - IDS_2117 "Dobrodošli u 86Box!" - IDS_2118 "Uunutarnji kontroler" - IDS_2119 "Izlazi" - IDS_2120 "Nisu pronađene ROM datoteke" - IDS_2121 "Želite li spremiti postavke?" - IDS_2122 "Ovo će napraviti hard resetiranje emuliranog sistema." - IDS_2123 "Spremaj" - IDS_2124 "O programu 86Box" - IDS_2125 "86Box verzija " EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Provjeri BPB" + IDS_2089 "KB" + IDS_2090 "Nije moguće inicijalizirati renderer." + IDS_2091 "Standard" + IDS_2092 "%i stanje čekanja" + IDS_2093 "Tip" + IDS_2094 "Postavljanje PCap-a nije uspjelo" + IDS_2095 "Nema PCap uređaja" + IDS_2096 "Nevažeći PCap uređaj" + IDS_2097 "Standardna palica za igru s 2 tipke" + IDS_2098 "Standardna palica za igru s 4 tipke" + IDS_2099 "Standardna palica za igru s 6 tipke" + IDS_2100 "Standardna palica za igru s 8 tipke" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Bez" + IDS_2105 "Nije moguće učitati ubrzivače tipkovnice." + IDS_2106 "Nije moguće registrirati neobrađeni unos." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Disketa %i (%s): %ls" + IDS_2110 "Sve slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Sve datoteke (*.*)\0*.*\0" + IDS_2111 "Nije moguće inicijalizirati FreeType" + IDS_2112 "Nije moguće inicijalizirati SDL, SDL2.dll je potrebno" + IDS_2113 "Jeste li sigurni da želite hard resetirati emulirani sistem?" + IDS_2114 "Jeste li sigurni da želite zatvoriti 86Box?" + IDS_2115 "Nije moguće inicijalizirati GhostScript" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "MO slike (*.IM?;*.MDI)\0*.IM?;*.MDI\0Svi datoteke (*.*)\0*.*\0" + IDS_2118 "Dobrodošli u 86Box!" + IDS_2119 "Uunutarnji kontroler" + IDS_2120 "Izlazi" + IDS_2121 "Nisu pronađene ROM datoteke" + IDS_2122 "Želite li spremiti postavke?" + IDS_2123 "Ovo će napraviti hard resetiranje emuliranog sistema." + IDS_2124 "Spremaj" + IDS_2125 "O programu 86Box" + IDS_2126 "86Box verzija " EMU_VERSION - IDS_2126 "Emulator starih računala\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." - IDS_2127 "U redu" - IDS_2128 "Hardver nije dostupan" + IDS_2127 "Emulator starih računala\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." + IDS_2128 "U redu" + IDS_2129 "Hardver nije dostupan" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Provjerite je li " LIB_NAME_PCAP " instaliran i jeste li na mreži, kompadibilnoj s " LIB_NAME_PCAP "." - IDS_2130 "Nevažeća konfiguracija" + IDS_2130 "Provjerite je li " LIB_NAME_PCAP " instaliran i jeste li na mreži, kompadibilnoj s " LIB_NAME_PCAP "." + IDS_2131 "Nevažeća konfiguracija" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " je potrebno za emuliranje ESC/P pisača." + IDS_2132 LIB_NAME_FREETYPE " je potrebno za emuliranje ESC/P pisača." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." + IDS_2133 LIB_NAME_GS " je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " je potrebno za FluidSynth MIDI izlaz." - IDS_2134 "Ulazim u cijelozaslonski način" - IDS_2135 "Ne pokazi više ovu poruku" - IDS_2136 "Ne izlazi" - IDS_2137 "Resetiraj" - IDS_2138 "Ne resetiraj" - IDS_2139 "MO slike (*.IM?;*.MDI)\0*.IM?;*.MDI\0Sve datoteke (*.*)\0*.*\0" - IDS_2140 "CD-ROM slike (*.ISO;*.CUE)\0*.ISO;*.CUE\0Sve datoteke (*.*)\0*.*\0" - IDS_2141 "Konfiguracija uređaja %hs " - IDS_2142 "Ekran u stanju mirovanja" - IDS_2143 "OpenGL shaderi (*.GLSL)\0*.GLSL\0Sve datoteke (*.*)\0*.*\0" - IDS_2144 "OpenGL opcije" - IDS_2145 "Učitavate nepodržanu konfiguraciju" - IDS_2146 "Filtriranje tipa CPU-a na temelju odabranog sistema onemogućeno je za ovaj emulirani sistem.\n\nOvo omogućuje odabir procesora koji inače nisu kompatibilne s odabranog sistem. Međutim, možete naići na na nekompatibilnosti s BIOS-om sustava ili drugim softverom.\n\nOmogućavanje ove postavke nije službeno podržano i sva prijava o greškama mogu biti zatvorena kao ""invalid""." - IDS_2147 "Nastavi" - IDS_2148 "Audio kaseta: %s" - IDS_2149 "Slike audio kasete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Sve datoteke (*.*)\0*.*\0" - IDS_2150 "Kaseta %i: %ls" - IDS_2151 "Slike kasete (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Sve datoteke (*.*)\0*.*\0" - IDS_2152 "Nije moguće inicijalizirati renderer" - IDS_2153 "Nije moguće inicijalizirati OpenGL (3.0 jezgra) renderer. Molimte koristite drugi renderer." - IDS_2154 "Nastavi" - IDS_2155 "Pauziraj" - IDS_2156 "Stisni Ctrl+Alt+Del" - IDS_2157 "Stisni Ctrl+Alt+Esc" - IDS_2158 "Ponovno pokretanje" - IDS_2159 "ACPI bazirano gašenje" - IDS_2160 "Postavke" - IDS_2161 "Raniji pogon" + IDS_2134 LIB_NAME_FLUIDSYNTH " je potrebno za FluidSynth MIDI izlaz." + IDS_2135 "Ulazim u cijelozaslonski način" + IDS_2136 "Ne pokazi više ovu poruku" + IDS_2137 "Ne izlazi" + IDS_2138 "Resetiraj" + IDS_2139 "Ne resetiraj" + IDS_2140 "MO slike (*.IM?;*.MDI)\0*.IM?;*.MDI\0Sve datoteke (*.*)\0*.*\0" + IDS_2141 "CD-ROM slike (*.ISO;*.CUE)\0*.ISO;*.CUE\0Sve datoteke (*.*)\0*.*\0" + IDS_2142 "Konfiguracija uređaja %hs " + IDS_2143 "Ekran u stanju mirovanja" + IDS_2144 "OpenGL shaderi (*.GLSL)\0*.GLSL\0Sve datoteke (*.*)\0*.*\0" + IDS_2145 "OpenGL opcije" + IDS_2146 "Učitavate nepodržanu konfiguraciju" + IDS_2147 "Filtriranje tipa CPU-a na temelju odabranog sistema onemogućeno je za ovaj emulirani sistem.\n\nOvo omogućuje odabir procesora koji inače nisu kompatibilne s odabranog sistem. Međutim, možete naići na na nekompatibilnosti s BIOS-om sustava ili drugim softverom.\n\nOmogućavanje ove postavke nije službeno podržano i sva prijava o greškama mogu biti zatvorena kao ""invalid""." + IDS_2148 "Nastavi" + IDS_2149 "Audio kaseta: %s" + IDS_2150 "Slike audio kasete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Sve datoteke (*.*)\0*.*\0" + IDS_2151 "Kaseta %i: %ls" + IDS_2152 "Slike kasete (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Sve datoteke (*.*)\0*.*\0" + IDS_2153 "Nije moguće inicijalizirati renderer" + IDS_2154 "Nije moguće inicijalizirati OpenGL (3.0 jezgra) renderer. Molimte koristite drugi renderer." + IDS_2155 "Nastavi" + IDS_2156 "Pauziraj" + IDS_2157 "Stisni Ctrl+Alt+Del" + IDS_2158 "Stisni Ctrl+Alt+Esc" + IDS_2159 "Ponovno pokretanje" + IDS_2160 "ACPI bazirano gašenje" + IDS_2161 "Postavke" + IDS_2162 "Raniji pogon" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index bdf122d5e..0ffa215c0 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -39,6 +39,7 @@ BEGIN MENUITEM "Állapotsor &elrejtése", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Átméretezhető ablak", IDM_VID_RESIZE MENUITEM "Méret és pozíció &megjegyzése", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -182,7 +183,7 @@ BEGIN MENUITEM "Előző képfájl &újratöltése", IDM_CDROM_RELOAD MENUITEM SEPARATOR MENUITEM "&Meglévő képfájl &megnyitása...", IDM_CDROM_IMAGE - MENUITEM "&Mappa", IDM_CDROM_DIR + MENUITEM "&Mappa...", IDM_CDROM_DIR END END @@ -276,6 +277,7 @@ END #define STR_DYNAREC "Dinamikus újrafordítás" #define STR_VIDEO "Videokártya:" +#define STR_VIDEO_2 "Videokártya 2:" #define STR_VOODOO "Voodoo-gyorsítókártya" #define STR_IBM8514 "IBM 8514/a-gyorsítókártya" #define STR_XGA "XGA-gyorsítókártya" @@ -338,6 +340,7 @@ END #define STR_BUS "Busz:" #define STR_CHANNEL "Csatorna:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Kiválasztás..." #define STR_SECTORS "Szektor:" @@ -427,101 +430,102 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "BPB ellenőrzése" - IDS_2088 "KB" - IDS_2089 "Nem sikerült inicializálni a videó megjelenítőt." - IDS_2090 "Alapértelmezett" - IDS_2091 "%i várakozási ciklus(ok)" - IDS_2092 "Típus" - IDS_2093 "Nem sikerült a PCap beállítása" - IDS_2094 "Nem találhatóak PCap eszközök" - IDS_2095 "Érvénytelen PCap eszköz" - IDS_2096 "Szabványos 2-gombos játékvezérlő(k)" - IDS_2097 "Szabványos 4-gombos játékvezérlő" - IDS_2098 "Szabványos 6-gombos játékvezérlő" - IDS_2099 "Szabványos 8-gombos játékvezérlő" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Nincs" - IDS_2104 "Nem lehet betölteni a billentyűzetgyorsítókat." - IDS_2105 "A közvetlen nyers bevitel regisztrálása nem sikerült." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Floppy %i (%s): %ls" - IDS_2109 "Minden képfájl (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Továbbfejlesztett szektor képek (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Alapvető szektor képek (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux képekfájlok (*.FDI)\0*.FDI\0Felületi képfájlok (*.86F;*.MFM)\0*.86F;*.MFM\0Minden fájl (*.*)\0*.*\0" - IDS_2110 "A FreeType inicializálása nem lehetséges" - IDS_2111 "Az SDL inicializálása nem lehetséges, az SDL2.dll fájl szükséges" - IDS_2112 "Biztosan szeretné újraindítani az emulált gépet?" - IDS_2113 "Biztos benne, hogy ki szeretne lépni a 86Box-ból?" - IDS_2114 "Nem sikerült inicializálni a Ghostscript-et" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "MO-képfájlok (*.IM?;*.MDI)\0*.IM?;*.MDI\0Minden fájl (*.*)\0*.*\0" - IDS_2117 "Üdvözli önt az 86Box!" - IDS_2118 "Integrált vezérlő" - IDS_2119 "Kilépés" - IDS_2120 "Nem találhatóak meg a ROM-képek" - IDS_2121 "Szeretné menteni a beállításokat?" - IDS_2122 "Ezzel hardveresen újraindítja az emulált gépet." - IDS_2123 "Mentés" - IDS_2124 "A 86Box névjegye" - IDS_2125 "86Box v" EMU_VERSION - IDS_2126 "Régi számítógépek emulátora\n\nFejlesztők: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." - IDS_2127 "OK" - IDS_2128 "Hardver nem elérhető" + IDS_2087 "Speed" + IDS_2088 "BPB ellenőrzése" + IDS_2089 "KB" + IDS_2090 "Nem sikerült inicializálni a videó megjelenítőt." + IDS_2091 "Alapértelmezett" + IDS_2092 "%i várakozási ciklus(ok)" + IDS_2093 "Típus" + IDS_2094 "Nem sikerült a PCap beállítása" + IDS_2095 "Nem találhatóak PCap eszközök" + IDS_2096 "Érvénytelen PCap eszköz" + IDS_2097 "Szabványos 2-gombos játékvezérlő(k)" + IDS_2098 "Szabványos 4-gombos játékvezérlő" + IDS_2099 "Szabványos 6-gombos játékvezérlő" + IDS_2100 "Szabványos 8-gombos játékvezérlő" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Nincs" + IDS_2105 "Nem lehet betölteni a billentyűzetgyorsítókat." + IDS_2106 "A közvetlen nyers bevitel regisztrálása nem sikerült." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Floppy %i (%s): %ls" + IDS_2110 "Minden képfájl (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Továbbfejlesztett szektor képek (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Alapvető szektor képek (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux képekfájlok (*.FDI)\0*.FDI\0Felületi képfájlok (*.86F;*.MFM)\0*.86F;*.MFM\0Minden fájl (*.*)\0*.*\0" + IDS_2111 "A FreeType inicializálása nem lehetséges" + IDS_2112 "Az SDL inicializálása nem lehetséges, az SDL2.dll fájl szükséges" + IDS_2113 "Biztosan szeretné újraindítani az emulált gépet?" + IDS_2114 "Biztos benne, hogy ki szeretne lépni a 86Box-ból?" + IDS_2115 "Nem sikerült inicializálni a Ghostscript-et" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "MO-képfájlok (*.IM?;*.MDI)\0*.IM?;*.MDI\0Minden fájl (*.*)\0*.*\0" + IDS_2118 "Üdvözli önt az 86Box!" + IDS_2119 "Integrált vezérlő" + IDS_2120 "Kilépés" + IDS_2121 "Nem találhatóak meg a ROM-képek" + IDS_2122 "Szeretné menteni a beállításokat?" + IDS_2123 "Ezzel hardveresen újraindítja az emulált gépet." + IDS_2124 "Mentés" + IDS_2125 "A 86Box névjegye" + IDS_2126 "86Box v" EMU_VERSION + IDS_2127 "Régi számítógépek emulátora\n\nFejlesztők: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." + IDS_2128 "OK" + IDS_2129 "Hardver nem elérhető" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Győződjön meg hogy a(z) " LIB_NAME_PCAP " telepítve van és jelenleg a " LIB_NAME_PCAP "-kompatibilis kapcsolatot használja." - IDS_2130 "Érvénytelen konfiguráció" + IDS_2130 "Győződjön meg hogy a(z) " LIB_NAME_PCAP " telepítve van és jelenleg a " LIB_NAME_PCAP "-kompatibilis kapcsolatot használja." + IDS_2131 "Érvénytelen konfiguráció" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " szükséges az ESC/P nyomtató emulációhoz." + IDS_2132 LIB_NAME_FREETYPE " szükséges az ESC/P nyomtató emulációhoz." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." + IDS_2133 LIB_NAME_GS " szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " szükséges a FluidSynth MIDI kimenethez." - IDS_2134 "Teljes képernyős módra váltás" - IDS_2135 "Ne jelenítse meg újra ezt az üzenetet " - IDS_2136 "Ne lépjen ki" - IDS_2137 "Újraindítás" - IDS_2138 "Ne indítsa újra" - IDS_2139 "MO-képfájlok (*.IM?;*.MDI)\0*.IM?;*.MDI\0Minden fájl (*.*)\0*.*\0" - IDS_2140 "CD-ROM-képek (*.ISO;*.CUE)\0*.ISO;*.CUE\0Minden fájl (*.*)\0*.*\0" - IDS_2141 "%hs eszközkonfiguráció" - IDS_2142 "Képernyő alvó módban" - IDS_2143 "OpenGL Shaderek (*.GLSL)\0*.GLSL\0Minden fájl (*.*)\0*.*\0" - IDS_2144 "OpenGL beállítások" - IDS_2145 "Egy nem támogatott konfigurációt tölt be" - IDS_2146 "A kiválasztott gépen alapuló CPU-típusszűrés le van tiltva ezen az emulált gépen.\n\nEz lehetővé teszi olyan CPU kiválasztását, amely egyébként nem kompatibilis a kiválasztott géppel. Előfordulhat azonban, hogy nem kompatibilis a gép BIOS-ával vagy más szoftverekkel.\n\nA beállítás engedélyezése hivatalosan nem támogatott, és a benyújtott hibajelentéseket érvénytelenként lezárhatjuk." - IDS_2147 "Folytatás" - IDS_2148 "Magnókazetta: %s" - IDS_2149 "Magnókazetta-képek (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Minden fájl (*.*)\0*.*\0" - IDS_2150 "ROM-kazetta %i: %ls" - IDS_2151 "ROM-kazetta képek (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Minden fájl (*.*)\0*.*\0" - IDS_2152 "Hiba történt a renderelő inicializálásakor" - IDS_2153 "Az OpenGL (3.0 Core) megjelenítő-motort nem sikerült inicializálni. Kérem használjon másik renderelőt." - IDS_2154 "Resume execution" - IDS_2155 "Pause execution" - IDS_2156 "Press Ctrl+Alt+Del" - IDS_2157 "Press Ctrl+Alt+Esc" - IDS_2158 "Hard reset" - IDS_2159 "ACPI shutdown" - IDS_2160 "Settings" - IDS_2161 "Korábbi meghajtó" + IDS_2134 LIB_NAME_FLUIDSYNTH " szükséges a FluidSynth MIDI kimenethez." + IDS_2135 "Teljes képernyős módra váltás" + IDS_2136 "Ne jelenítse meg újra ezt az üzenetet " + IDS_2137 "Ne lépjen ki" + IDS_2138 "Újraindítás" + IDS_2139 "Ne indítsa újra" + IDS_2140 "MO-képfájlok (*.IM?;*.MDI)\0*.IM?;*.MDI\0Minden fájl (*.*)\0*.*\0" + IDS_2141 "CD-ROM-képek (*.ISO;*.CUE)\0*.ISO;*.CUE\0Minden fájl (*.*)\0*.*\0" + IDS_2142 "%hs eszközkonfiguráció" + IDS_2143 "Képernyő alvó módban" + IDS_2144 "OpenGL Shaderek (*.GLSL)\0*.GLSL\0Minden fájl (*.*)\0*.*\0" + IDS_2145 "OpenGL beállítások" + IDS_2146 "Egy nem támogatott konfigurációt tölt be" + IDS_2147 "A kiválasztott gépen alapuló CPU-típusszűrés le van tiltva ezen az emulált gépen.\n\nEz lehetővé teszi olyan CPU kiválasztását, amely egyébként nem kompatibilis a kiválasztott géppel. Előfordulhat azonban, hogy nem kompatibilis a gép BIOS-ával vagy más szoftverekkel.\n\nA beállítás engedélyezése hivatalosan nem támogatott, és a benyújtott hibajelentéseket érvénytelenként lezárhatjuk." + IDS_2148 "Folytatás" + IDS_2149 "Magnókazetta: %s" + IDS_2150 "Magnókazetta-képek (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Minden fájl (*.*)\0*.*\0" + IDS_2151 "ROM-kazetta %i: %ls" + IDS_2152 "ROM-kazetta képek (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Minden fájl (*.*)\0*.*\0" + IDS_2153 "Hiba történt a renderelő inicializálásakor" + IDS_2154 "Az OpenGL (3.0 Core) megjelenítő-motort nem sikerült inicializálni. Kérem használjon másik renderelőt." + IDS_2155 "Resume execution" + IDS_2156 "Pause execution" + IDS_2157 "Press Ctrl+Alt+Del" + IDS_2158 "Press Ctrl+Alt+Esc" + IDS_2159 "Hard reset" + IDS_2160 "ACPI shutdown" + IDS_2161 "Settings" + IDS_2162 "Korábbi meghajtó" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc index ffcfe64d9..960e9e205 100644 --- a/src/win/languages/it-IT.rc +++ b/src/win/languages/it-IT.rc @@ -35,6 +35,7 @@ BEGIN MENUITEM "&Nascondi barra di stato", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Finestra ridimensionabile", IDM_VID_RESIZE MENUITEM "R&icorda dimensioni e posizione", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -177,8 +178,8 @@ BEGIN MENUITEM "&Espelli", IDM_CDROM_EMPTY MENUITEM "&Ricarica l'immagine precedente", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Immagine", IDM_CDROM_IMAGE - MENUITEM "&Cartella", IDM_CDROM_DIR + MENUITEM "&Immagine...", IDM_CDROM_IMAGE + MENUITEM "&Cartella...", IDM_CDROM_DIR END END @@ -272,6 +273,7 @@ END #define STR_DYNAREC "Ricompilatore dinamico" #define STR_VIDEO "Video:" +#define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Grafica Voodoo" #define STR_IBM8514 "Grafica IBM 8514/a" #define STR_XGA "Grafica XGA" @@ -334,6 +336,7 @@ END #define STR_BUS "Bus:" #define STR_CHANNEL "Canale:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Specifica..." #define STR_SECTORS "Settori:" @@ -423,102 +426,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Verifica BPB" - IDS_2088 "KB" - IDS_2089 "Impossibile inizializzare il renderer video." - IDS_2090 "Predefinito" - IDS_2091 "%i stati d'attesa" - IDS_2092 "Tipo" - IDS_2093 "Impossibile impostare PCap" - IDS_2094 "Nessun dispositivo PCap trovato" - IDS_2095 "Dispositivo PCap invalido" - IDS_2096 "Joystick comune da 2 pulsanti" - IDS_2097 "Joystick comune da 4 pulsanti" - IDS_2098 "Joystick comune da 6 pulsanti" - IDS_2099 "Joystick comune da 8 pulsanti" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Nessuno" - IDS_2104 "Impossibile caricare gli acceleratori da tastiera." - IDS_2105 "Impossibile registrare input raw." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Floppy %i (%s): %ls" - IDS_2109 "Tutte le immagini (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Immagini da settori avanzati (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagini da settori basilari (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Immagini flusso (*.FDI)\0*.FDI\0Immagini da superficie (*.86F;*.MFM)\0*.86F;*.MFM\0Tutti i file (*.*)\0*.*\0" - IDS_2110 "Impossibile inizializzare FreeType" - IDS_2111 "Impossibile inizializzare SDL, SDL2.dll è necessario" - IDS_2112 "Sei sicuro di voler riavviare la macchina emulata?" - IDS_2113 "Sei sicuro di voler uscire da 86Box?" - IDS_2114 "Impossibile inizializzare Ghostscript" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "Immagini MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tutti i file (*.*)\0*.*\0" - IDS_2117 "Benvenuti in 86Box!" - IDS_2118 "Controller interno" - IDS_2119 "Esci" - IDS_2120 "Nessune immagini ROM trovate" - IDS_2121 "Vuole salvare queste impostazioni?" - IDS_2122 "Questo riavvierà la macchina emulata." - IDS_2123 "Salva" - IDS_2124 "Informazioni su 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Verifica BPB" + IDS_2089 "KB" + IDS_2090 "Impossibile inizializzare il renderer video." + IDS_2091 "Predefinito" + IDS_2092 "%i stati d'attesa" + IDS_2093 "Tipo" + IDS_2094 "Impossibile impostare PCap" + IDS_2095 "Nessun dispositivo PCap trovato" + IDS_2096 "Dispositivo PCap invalido" + IDS_2097 "Joystick comune da 2 pulsanti" + IDS_2098 "Joystick comune da 4 pulsanti" + IDS_2099 "Joystick comune da 6 pulsanti" + IDS_2100 "Joystick comune da 8 pulsanti" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Nessuno" + IDS_2105 "Impossibile caricare gli acceleratori da tastiera." + IDS_2106 "Impossibile registrare input raw." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Floppy %i (%s): %ls" + IDS_2110 "Tutte le immagini (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Immagini da settori avanzati (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagini da settori basilari (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Immagini flusso (*.FDI)\0*.FDI\0Immagini da superficie (*.86F;*.MFM)\0*.86F;*.MFM\0Tutti i file (*.*)\0*.*\0" + IDS_2111 "Impossibile inizializzare FreeType" + IDS_2112 "Impossibile inizializzare SDL, SDL2.dll è necessario" + IDS_2113 "Sei sicuro di voler riavviare la macchina emulata?" + IDS_2114 "Sei sicuro di voler uscire da 86Box?" + IDS_2115 "Impossibile inizializzare Ghostscript" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "Immagini MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tutti i file (*.*)\0*.*\0" + IDS_2118 "Benvenuti in 86Box!" + IDS_2119 "Controller interno" + IDS_2120 "Esci" + IDS_2121 "Nessune immagini ROM trovate" + IDS_2122 "Vuole salvare queste impostazioni?" + IDS_2123 "Questo riavvierà la macchina emulata." + IDS_2124 "Salva" + IDS_2125 "Informazioni su 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "Un emulatore di computer vecchi\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." - IDS_2127 "OK" - IDS_2128 "Hardware non disponibile" + IDS_2127 "Un emulatore di computer vecchi\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." + IDS_2128 "OK" + IDS_2129 "Hardware non disponibile" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Controlla se " LIB_NAME_PCAP " è installato e che tu sia connesso ad una connessione " LIB_NAME_PCAP " compatibile." - IDS_2130 "Configurazione invalida" + IDS_2130 "Controlla se " LIB_NAME_PCAP " è installato e che tu sia connesso ad una connessione " LIB_NAME_PCAP " compatibile." + IDS_2131 "Configurazione invalida" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " è richesto per l'emuazione di stampanti ESC/P." + IDS_2132 LIB_NAME_FREETYPE " è richesto per l'emuazione di stampanti ESC/P." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" + IDS_2133 LIB_NAME_GS " è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " è richiesto per l'output FluidSynth MIDI." - IDS_2134 "Entrando nella modalità schermo intero" - IDS_2135 "Non mostrare più questo messaggio" - IDS_2136 "Non uscire" - IDS_2137 "Riavvia" - IDS_2138 "Non riavviare" - IDS_2139 "Immagini MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tutti i file (*.*)\0*.*\0" - IDS_2140 "Immagini CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tutti i file (*.*)\0*.*\0" - IDS_2141 "Configurazione del dispositivo %hs" - IDS_2142 "Monitor in modalità riposo" - IDS_2143 "Shader OpenGL (*.GLSL)\0*.GLSL\0Tutti i file (*.*)\0*.*\0" - IDS_2144 "Impostazioni OpenGL" - IDS_2145 "Stai caricando una configurazione non supportata" - IDS_2146 "Il filtraggio della tipologia di CPU è disabilitato per la macchina selezionata.\n\nQuesto lo rende possibile scegliere un CPU che è altrimenti incompatibile con la macchina selezionata. Tuttavia, portresti incorrere in incompatibilità con il BIOS della macchina o altri programmi. \n\nL'abilitare di questa impostazione non è ufficialmente supportato e tutte le segnalazioni di errori saranno considerate invalide." - IDS_2147 "Continua" - IDS_2148 "Cassetta: %s" - IDS_2149 "Immagini cassetta (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tutti i file (*.*)\0*.*\0" - IDS_2150 "Cartuccia %i: %ls" - IDS_2151 "Immagini cartuccia (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tutti i file (*.*)\0*.*\0" - IDS_2152 "Error initializing renderer" - IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2154 "Resume execution" - IDS_2155 "Pause execution" - IDS_2156 "Press Ctrl+Alt+Del" - IDS_2157 "Press Ctrl+Alt+Esc" - IDS_2158 "Hard reset" - IDS_2159 "ACPI shutdown" - IDS_2160 "Settings" - IDS_2161 "Unità anteriore" + IDS_2134 LIB_NAME_FLUIDSYNTH " è richiesto per l'output FluidSynth MIDI." + IDS_2135 "Entrando nella modalità schermo intero" + IDS_2136 "Non mostrare più questo messaggio" + IDS_2137 "Non uscire" + IDS_2138 "Riavvia" + IDS_2139 "Non riavviare" + IDS_2140 "Immagini MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tutti i file (*.*)\0*.*\0" + IDS_2141 "Immagini CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tutti i file (*.*)\0*.*\0" + IDS_2142 "Configurazione del dispositivo %hs" + IDS_2143 "Monitor in modalità riposo" + IDS_2144 "Shader OpenGL (*.GLSL)\0*.GLSL\0Tutti i file (*.*)\0*.*\0" + IDS_2145 "Impostazioni OpenGL" + IDS_2146 "Stai caricando una configurazione non supportata" + IDS_2147 "Il filtraggio della tipologia di CPU è disabilitato per la macchina selezionata.\n\nQuesto lo rende possibile scegliere un CPU che è altrimenti incompatibile con la macchina selezionata. Tuttavia, portresti incorrere in incompatibilità con il BIOS della macchina o altri programmi. \n\nL'abilitare di questa impostazione non è ufficialmente supportato e tutte le segnalazioni di errori saranno considerate invalide." + IDS_2148 "Continua" + IDS_2149 "Cassetta: %s" + IDS_2150 "Immagini cassetta (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tutti i file (*.*)\0*.*\0" + IDS_2151 "Cartuccia %i: %ls" + IDS_2152 "Immagini cartuccia (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tutti i file (*.*)\0*.*\0" + IDS_2153 "Error initializing renderer" + IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." + IDS_2155 "Resume execution" + IDS_2156 "Pause execution" + IDS_2157 "Press Ctrl+Alt+Del" + IDS_2158 "Press Ctrl+Alt+Esc" + IDS_2159 "Hard reset" + IDS_2160 "ACPI shutdown" + IDS_2161 "Settings" + IDS_2162 "Unità anteriore" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index c1bd10e18..edcf3f668 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "ステータスバーを隠す(&H)", IDM_VID_HIDE_STATUS_BAR MENUITEM "ツールバーを隠す(&T)", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "ウィンドウのサイズをリサイズ可能(&R)", IDM_VID_RESIZE MENUITEM "ウィンドウのサイズと位置を記憶(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "空(&M)", IDM_CDROM_EMPTY MENUITEM "前のイメージを再読み込み(&R)", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "イメージ(&I)", IDM_CDROM_IMAGE - MENUITEM "フォルダ(&F)", IDM_CDROM_DIR + MENUITEM "イメージ(&I)...", IDM_CDROM_IMAGE + MENUITEM "フォルダ(&F)...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "動的リコンパイラ" #define STR_VIDEO "ビデオカード:" +#define STR_VIDEO_2 "ビデオカード 2:" #define STR_VOODOO "Voodooグラフィック" #define STR_IBM8514 "IBM 8514/aグラフィック" #define STR_XGA "XGAグラフィック" @@ -333,6 +335,7 @@ END #define STR_BUS "バス:" #define STR_CHANNEL "チャンネル:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "参照(&S)..." #define STR_SECTORS "セクター:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "BPBをチェック" - IDS_2088 "KB" - IDS_2089 "ビデオレンダラーが初期化できません。" - IDS_2090 "既定値" - IDS_2091 "%iつの待機状態" - IDS_2092 "タイプ" - IDS_2093 "PCapのセットアップに失敗しました" - IDS_2094 "PCapデバイスがありません" - IDS_2095 "不正なPCapデバイスです" - IDS_2096 "標準ジョイスティック(2ボタン)" - IDS_2097 "標準ジョイスティック(4ボタン)" - IDS_2098 "標準ジョイスティック(6ボタン)" - IDS_2099 "標準ジョイスティック(8ボタン)" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "なし" - IDS_2104 "キーボードアクセラレータを読み込めません。" - IDS_2105 "生の入力が登録できません。" - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "フロッピー %i (%s): %ls" - IDS_2109 "すべてのイメージ (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0アドバンスドセクターイメージ (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本セクターイメージ (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0フラックスイメージ (*.FDI)\0*.FDI\0表面イメージ (*.86F;*.MFM)\0*.86F;*.MFM\0すべてのファイル (*.*)\0*.*\0" - IDS_2110 "FreeTypeが初期化できません" - IDS_2111 "SDLが初期化できません。SDL2.dllが必要です" - IDS_2112 "使用中のマシンをハードリセットしますか?" - IDS_2113 "86Boxを終了しますか?" - IDS_2114 "Ghostscriptが初期化できません" - IDS_2115 "光磁気 %i (%ls): %ls" - IDS_2116 "光磁気イメージ (*.IM?;*.MDI)\0*.IM?;*.MDI\0すべてのファイル (*.*)\0*.*\0" - IDS_2117 "86Boxへようこそ!" - IDS_2118 "内蔵コントローラー" - IDS_2119 "終了" - IDS_2120 "ROMが見つかりません" - IDS_2121 "設定を保存しますか?" - IDS_2122 "保存すると使用中のマシンがハードリセットされます。" - IDS_2123 "保存" - IDS_2124 "86Boxのバージョン情報" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "BPBをチェック" + IDS_2089 "KB" + IDS_2090 "ビデオレンダラーが初期化できません。" + IDS_2091 "既定値" + IDS_2092 "%iつの待機状態" + IDS_2093 "タイプ" + IDS_2094 "PCapのセットアップに失敗しました" + IDS_2095 "PCapデバイスがありません" + IDS_2096 "不正なPCapデバイスです" + IDS_2097 "標準ジョイスティック(2ボタン)" + IDS_2098 "標準ジョイスティック(4ボタン)" + IDS_2099 "標準ジョイスティック(6ボタン)" + IDS_2100 "標準ジョイスティック(8ボタン)" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "なし" + IDS_2105 "キーボードアクセラレータを読み込めません。" + IDS_2106 "生の入力が登録できません。" + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "フロッピー %i (%s): %ls" + IDS_2110 "すべてのイメージ (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0アドバンスドセクターイメージ (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本セクターイメージ (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0フラックスイメージ (*.FDI)\0*.FDI\0表面イメージ (*.86F;*.MFM)\0*.86F;*.MFM\0すべてのファイル (*.*)\0*.*\0" + IDS_2111 "FreeTypeが初期化できません" + IDS_2112 "SDLが初期化できません。SDL2.dllが必要です" + IDS_2113 "使用中のマシンをハードリセットしますか?" + IDS_2114 "86Boxを終了しますか?" + IDS_2115 "Ghostscriptが初期化できません" + IDS_2116 "光磁気 %i (%ls): %ls" + IDS_2117 "光磁気イメージ (*.IM?;*.MDI)\0*.IM?;*.MDI\0すべてのファイル (*.*)\0*.*\0" + IDS_2118 "86Boxへようこそ!" + IDS_2119 "内蔵コントローラー" + IDS_2120 "終了" + IDS_2121 "ROMが見つかりません" + IDS_2122 "設定を保存しますか?" + IDS_2123 "保存すると使用中のマシンがハードリセットされます。" + IDS_2124 "保存" + IDS_2125 "86Boxのバージョン情報" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "古いパソコンのエミュレーター\n\n著者: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" - IDS_2127 "OK" - IDS_2128 "ハードウェアが利用できません" + IDS_2127 "古いパソコンのエミュレーター\n\n著者: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" + IDS_2128 "OK" + IDS_2129 "ハードウェアが利用できません" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 LIB_NAME_PCAP "がインストールされてるか、" LIB_NAME_PCAP "に対応したネットワークに接続されてるか確認してください。" - IDS_2130 "不正な設定です" + IDS_2130 LIB_NAME_PCAP "がインストールされてるか、" LIB_NAME_PCAP "に対応したネットワークに接続されてるか確認してください。" + IDS_2131 "不正な設定です" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 "ESC/Pプリンタのエミュレーションには" LIB_NAME_FREETYPE "が必要です。" + IDS_2132 "ESC/Pプリンタのエミュレーションには" LIB_NAME_FREETYPE "が必要です。" #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 "PostScriptファイルをPDFに自動変換するには" LIB_NAME_GS "が必要です。\n\n汎用PostScriptプリンターに送信されたドキュメントは、PostScript(.ps)ファイルとして保存されます。" + IDS_2133 "PostScriptファイルをPDFに自動変換するには" LIB_NAME_GS "が必要です。\n\n汎用PostScriptプリンターに送信されたドキュメントは、PostScript(.ps)ファイルとして保存されます。" #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 "FluidSynthのMIDI出力には" LIB_NAME_FLUIDSYNTH "が必要です。" - IDS_2134 "フルスクリーンに切り替えています" - IDS_2135 "今後、このメッセージを表示しない" - IDS_2136 "終了しない" - IDS_2137 "リセット" - IDS_2138 "リセットしない" - IDS_2139 "光磁気イメージ (*.IM?;*.MDI)\0*.IM?;*.MDI\0すべてのファイル (*.*)\0*.*\0" - IDS_2140 "CD-ROMイメージ (*.ISO;*.CUE)\0*.ISO;*.CUE\0すべてのファイル (*.*)\0*.*\0" - IDS_2141 "%hs デバイスの設定" - IDS_2142 "モニターのスリープモード" - IDS_2143 "OpenGLシェーダー (*.GLSL)\0*.GLSL\0すべてのファイル (*.*)\0*.*\0" - IDS_2144 "OpenGL設定" - IDS_2145 "サポートされていない設定を読み込んでいます" - IDS_2146 "選択したマシンに基づくCPUタイプのフィルタリングは、このエミュレートされたマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。ただし、マシンのBIOSまたは他のソフトウェアとの互換性が失われる可能性があります。\n\nこの設定の有効化は公式サポートができません。また、バグレポートが無効として閉じられる場合があります。" - IDS_2147 "続行" - IDS_2148 "カセット: %s" - IDS_2149 "カセットイメージ (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0すべてのファイル (*.*)\0*.*\0" - IDS_2150 "カートリッジ %i: %ls" - IDS_2151 "カートリッジイメージ (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0すべてのファイル (*.*)\0*.*\0" - IDS_2152 "レンダラーの初期化エラー" - IDS_2153 "OpenGL (3.0コア) レンダラーが初期化できませんでした。別のレンダラーを使用してください。" - IDS_2154 "実行を再開" - IDS_2155 "実行を一時停止" - IDS_2156 "Ctrl+Alt+DELを押し" - IDS_2157 "Ctrl+Alt+Escを押し" - IDS_2158 "ハードリセット" - IDS_2159 "ACPIシャットダウン" - IDS_2160 "設定" - IDS_2161 "アーリードライブ" + IDS_2134 "FluidSynthのMIDI出力には" LIB_NAME_FLUIDSYNTH "が必要です。" + IDS_2135 "フルスクリーンに切り替えています" + IDS_2136 "今後、このメッセージを表示しない" + IDS_2137 "終了しない" + IDS_2138 "リセット" + IDS_2139 "リセットしない" + IDS_2140 "光磁気イメージ (*.IM?;*.MDI)\0*.IM?;*.MDI\0すべてのファイル (*.*)\0*.*\0" + IDS_2141 "CD-ROMイメージ (*.ISO;*.CUE)\0*.ISO;*.CUE\0すべてのファイル (*.*)\0*.*\0" + IDS_2142 "%hs デバイスの設定" + IDS_2143 "モニターのスリープモード" + IDS_2144 "OpenGLシェーダー (*.GLSL)\0*.GLSL\0すべてのファイル (*.*)\0*.*\0" + IDS_2145 "OpenGL設定" + IDS_2146 "サポートされていない設定を読み込んでいます" + IDS_2147 "選択したマシンに基づくCPUタイプのフィルタリングは、このエミュレートされたマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。ただし、マシンのBIOSまたは他のソフトウェアとの互換性が失われる可能性があります。\n\nこの設定の有効化は公式サポートができません。また、バグレポートが無効として閉じられる場合があります。" + IDS_2148 "続行" + IDS_2149 "カセット: %s" + IDS_2150 "カセットイメージ (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0すべてのファイル (*.*)\0*.*\0" + IDS_2151 "カートリッジ %i: %ls" + IDS_2152 "カートリッジイメージ (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0すべてのファイル (*.*)\0*.*\0" + IDS_2153 "レンダラーの初期化エラー" + IDS_2154 "OpenGL (3.0コア) レンダラーが初期化できませんでした。別のレンダラーを使用してください。" + IDS_2155 "実行を再開" + IDS_2156 "実行を一時停止" + IDS_2157 "Ctrl+Alt+DELを押し" + IDS_2158 "Ctrl+Alt+Escを押し" + IDS_2159 "ハードリセット" + IDS_2160 "ACPIシャットダウン" + IDS_2161 "設定" + IDS_2162 "アーリードライブ" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index a43c9e3af..a5f0cfe57 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "상태 바 숨기기(&H)", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "창 크기 조절 가능하게 하기(&R)", IDM_VID_RESIZE MENUITEM "창 크기와 위치를 기억하기(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "비었음(&M)", IDM_CDROM_EMPTY MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "이미지(&I)", IDM_CDROM_IMAGE - MENUITEM "폴더(&F)", IDM_CDROM_DIR + MENUITEM "이미지(&I)...", IDM_CDROM_IMAGE + MENUITEM "폴더(&F)...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "동적 재컴파일" #define STR_VIDEO "비디오 카드:" +#define STR_VIDEO_2 "비디오 카드 2:" #define STR_VOODOO "Voodoo 그래픽" #define STR_IBM8514 "IBM 8514/a 그래픽" #define STR_XGA "XGA 그래픽" @@ -333,6 +335,7 @@ END #define STR_BUS "버스:" #define STR_CHANNEL "채널:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "열기(&S)..." #define STR_SECTORS "섹터:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "BPB 확인" - IDS_2088 "KB" - IDS_2089 "비디오 렌더러를 초기화할 수 없습니다." - IDS_2090 "기본값" - IDS_2091 "%i 대기 상태" - IDS_2092 "형식" - IDS_2093 "PCap 설정에 실패했습니다" - IDS_2094 "PCap 장치가 없습니다" - IDS_2095 "PCap 장치가 올바르지 않습니다" - IDS_2096 "표준 2버튼 조이스틱" - IDS_2097 "표준 4버튼 조이스틱" - IDS_2098 "표준 6버튼 조이스틱" - IDS_2099 "표준 8버튼 조이스틱" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "없음" - IDS_2104 "키보드 가속기를 불러올 수 없습니다." - IDS_2105 "Raw 입력을 등록할 수 없습니다." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "플로피 %i (%s): %ls" - IDS_2109 "모든 이미지 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0어드밴스드 섹터 이미지 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0기본 섹터 이미지 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0플럭스 이미지 (*.FDI)\0*.FDI\0표면 이미지 (*.86F;*.MFM)\0*.86F;*.MFM\0모든 파일 (*.*)\0*.*\0" - IDS_2110 "FreeType을 초기화할 수 없습니다" - IDS_2111 "SDL을 초기화할 수 없습니다. SDL2.dll이 필요합니다" - IDS_2112 "실행중인 머신을 재시작하시겠습니까?" - IDS_2113 "86Box를 끝내시겠습니까?" - IDS_2114 "Ghostscript를 초기화할 수 없습니다" - IDS_2115 "광자기 %i (%ls): %ls" - IDS_2116 "광자기 이미지 (*.IM?;*.MDI)\0*.IM?;*.MDI\0모든 파일 (*.*)\0*.*\0" - IDS_2117 "86Box에 어서오세요!" - IDS_2118 "내부 컨트롤러" - IDS_2119 "끝내기" - IDS_2120 "ROM을 불러올 수 없습니다" - IDS_2121 "설정을 저장하시겠습니까?" - IDS_2122 "사용중인 머신이 재부팅됩니다." - IDS_2123 "저장" - IDS_2124 "86Box에 대해" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "BPB 확인" + IDS_2089 "KB" + IDS_2090 "비디오 렌더러를 초기화할 수 없습니다." + IDS_2091 "기본값" + IDS_2092 "%i 대기 상태" + IDS_2093 "형식" + IDS_2094 "PCap 설정에 실패했습니다" + IDS_2095 "PCap 장치가 없습니다" + IDS_2096 "PCap 장치가 올바르지 않습니다" + IDS_2097 "표준 2버튼 조이스틱" + IDS_2098 "표준 4버튼 조이스틱" + IDS_2099 "표준 6버튼 조이스틱" + IDS_2100 "표준 8버튼 조이스틱" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "없음" + IDS_2105 "키보드 가속기를 불러올 수 없습니다." + IDS_2106 "Raw 입력을 등록할 수 없습니다." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "플로피 %i (%s): %ls" + IDS_2110 "모든 이미지 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0어드밴스드 섹터 이미지 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0기본 섹터 이미지 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0플럭스 이미지 (*.FDI)\0*.FDI\0표면 이미지 (*.86F;*.MFM)\0*.86F;*.MFM\0모든 파일 (*.*)\0*.*\0" + IDS_2111 "FreeType을 초기화할 수 없습니다" + IDS_2112 "SDL을 초기화할 수 없습니다. SDL2.dll이 필요합니다" + IDS_2113 "실행중인 머신을 재시작하시겠습니까?" + IDS_2114 "86Box를 끝내시겠습니까?" + IDS_2115 "Ghostscript를 초기화할 수 없습니다" + IDS_2116 "광자기 %i (%ls): %ls" + IDS_2117 "광자기 이미지 (*.IM?;*.MDI)\0*.IM?;*.MDI\0모든 파일 (*.*)\0*.*\0" + IDS_2118 "86Box에 어서오세요!" + IDS_2119 "내부 컨트롤러" + IDS_2120 "끝내기" + IDS_2121 "ROM을 불러올 수 없습니다" + IDS_2122 "설정을 저장하시겠습니까?" + IDS_2123 "사용중인 머신이 재부팅됩니다." + IDS_2124 "저장" + IDS_2125 "86Box에 대해" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "고전 컴퓨터 에뮬레이터\n\n저자: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." - IDS_2127 "확인" - IDS_2128 "하드웨어를 이용할 수 없습니다" + IDS_2127 "고전 컴퓨터 에뮬레이터\n\n저자: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." + IDS_2128 "확인" + IDS_2129 "하드웨어를 이용할 수 없습니다" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 LIB_NAME_PCAP "이 설치되었는지 " LIB_NAME_PCAP "에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." - IDS_2130 "올바르지 않은 설정입니다" + IDS_2130 LIB_NAME_PCAP "이 설치되었는지 " LIB_NAME_PCAP "에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." + IDS_2131 "올바르지 않은 설정입니다" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 "ESC/P 프린터 에뮬레이션에 " LIB_NAME_FREETYPE "이(가) 필요합니다." + IDS_2132 "ESC/P 프린터 에뮬레이션에 " LIB_NAME_FREETYPE "이(가) 필요합니다." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS "은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." + IDS_2133 LIB_NAME_GS "은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 "FluidSynth의 MIDI 출력에 " LIB_NAME_FLUIDSYNTH "이(가) 필요합니다." - IDS_2134 "전체 화면으로 전환" - IDS_2135 "이 메시지 그만 보기" - IDS_2136 "끝내지 않기" - IDS_2137 "재시작" - IDS_2138 "재시작 안함" - IDS_2139 "광자기 이미지 (*.IM?;*.MDI)\0*.IM?;*.MDI\0모든 파일 (*.*)\0*.*\0" - IDS_2140 "CD-ROM 이미지 (*.ISO;*.CUE)\0*.ISO;*.CUE\0모든 파일 (*.*)\0*.*\0" - IDS_2141 "%hs 장치 설정" - IDS_2142 "모니터 절전 모드" - IDS_2143 "OpenGL 쉐이더 (*.GLSL)\0*.GLSL\0모든 파일 (*.*)\0*.*\0" - IDS_2144 "OpenGL 설정" - IDS_2145 "지원하지 않는 설정입니다" - IDS_2146 "이 에뮬레이트된 기종에 대해 선택한 기종을 기반으로 하는 CPU 종류 필터링이 사용되지 않도록 설정되었습니다.\n\n따라서 선택된 머신과 호환되지 않는 CPU를 선택하실 수 있습니다. 하지만 BIOS 또는 다른 소프트웨어와 호환되지 않을 수 있습니다.\n\n이 설정을 활성화하는 것은 공식적으로 지원되지 않으며, 제출된 버그 보고서는 유효하지 않음으로 닫힐 수 있습니다." - IDS_2147 "계속" - IDS_2148 "카세트: %s" - IDS_2149 "카세트 이미지 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0모든 파일 (*.*)\0*.*\0" - IDS_2150 "카트리지 %i: %ls" - IDS_2151 "카트리지 이미지 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0모든 파일 (*.*)\0*.*\0" - IDS_2152 "렌더러 초기화 오류" - IDS_2153 "OpenGL (3.0 Core) 렌더러를 초기화할 수 없습니다. 다른 렌더러를 사용하십시오." - IDS_2154 "실행 재개" - IDS_2155 "실행 일시 중지" - IDS_2156 "Ctrl+Alt+Del" - IDS_2157 "Ctrl+Alt+Esc" - IDS_2158 "재시작" - IDS_2159 "ACPI 종료" - IDS_2160 "설정" - IDS_2161 "이전 드라이브" + IDS_2134 "FluidSynth의 MIDI 출력에 " LIB_NAME_FLUIDSYNTH "이(가) 필요합니다." + IDS_2135 "전체 화면으로 전환" + IDS_2136 "이 메시지 그만 보기" + IDS_2137 "끝내지 않기" + IDS_2138 "재시작" + IDS_2139 "재시작 안함" + IDS_2140 "광자기 이미지 (*.IM?;*.MDI)\0*.IM?;*.MDI\0모든 파일 (*.*)\0*.*\0" + IDS_2141 "CD-ROM 이미지 (*.ISO;*.CUE)\0*.ISO;*.CUE\0모든 파일 (*.*)\0*.*\0" + IDS_2142 "%hs 장치 설정" + IDS_2143 "모니터 절전 모드" + IDS_2144 "OpenGL 쉐이더 (*.GLSL)\0*.GLSL\0모든 파일 (*.*)\0*.*\0" + IDS_2145 "OpenGL 설정" + IDS_2146 "지원하지 않는 설정입니다" + IDS_2147 "이 에뮬레이트된 기종에 대해 선택한 기종을 기반으로 하는 CPU 종류 필터링이 사용되지 않도록 설정되었습니다.\n\n따라서 선택된 머신과 호환되지 않는 CPU를 선택하실 수 있습니다. 하지만 BIOS 또는 다른 소프트웨어와 호환되지 않을 수 있습니다.\n\n이 설정을 활성화하는 것은 공식적으로 지원되지 않으며, 제출된 버그 보고서는 유효하지 않음으로 닫힐 수 있습니다." + IDS_2148 "계속" + IDS_2149 "카세트: %s" + IDS_2150 "카세트 이미지 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0모든 파일 (*.*)\0*.*\0" + IDS_2151 "카트리지 %i: %ls" + IDS_2152 "카트리지 이미지 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0모든 파일 (*.*)\0*.*\0" + IDS_2153 "렌더러 초기화 오류" + IDS_2154 "OpenGL (3.0 Core) 렌더러를 초기화할 수 없습니다. 다른 렌더러를 사용하십시오." + IDS_2155 "실행 재개" + IDS_2156 "실행 일시 중지" + IDS_2157 "Ctrl+Alt+Del" + IDS_2158 "Ctrl+Alt+Esc" + IDS_2159 "재시작" + IDS_2160 "ACPI 종료" + IDS_2161 "설정" + IDS_2162 "이전 드라이브" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc index 9218936b9..ec59c5ef1 100644 --- a/src/win/languages/pl-PL.rc +++ b/src/win/languages/pl-PL.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Ukryj pasek statusu", IDM_VID_HIDE_STATUS_BAR MENUITEM "Ukryj &pasek narzędzi", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Okno o zmiennym rozmiarze", IDM_VID_RESIZE MENUITEM "P&amiętaj rozmiar &i pozycję", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "P&usty", IDM_CDROM_EMPTY MENUITEM "&Przeładuj poprzedni obraz", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Obraz", IDM_CDROM_IMAGE - MENUITEM "&Teczka", IDM_CDROM_DIR + MENUITEM "&Obraz...", IDM_CDROM_IMAGE + MENUITEM "&Teczka...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Dynamiczny rekompilator" #define STR_VIDEO "Wideo:" +#define STR_VIDEO_2 "Wideo 2:" #define STR_VOODOO "Grafika Voodoo" #define STR_IBM8514 "Grafika IBM 8514/a" #define STR_XGA "Grafika XGA" @@ -333,6 +335,7 @@ END #define STR_BUS "Magistrala:" #define STR_CHANNEL "Kanał:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Określ..." #define STR_SECTORS "Sektory:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Sprawdzaj BPB" - IDS_2088 "KB" - IDS_2089 "Nie można zainicjować renderera wideo." - IDS_2090 "Domyślny" - IDS_2091 "%i Stany oczekiwania" - IDS_2092 "Rodzaj" - IDS_2093 "Nie udało się ustawić PCap" - IDS_2094 "Nie znaleziono urządzeń PCap" - IDS_2095 "Nieprawidłowe urządzenie PCap" - IDS_2096 "Standardowe joysticki 2-przyciskowe" - IDS_2097 "Standardowy joystick 4-przyciskowy" - IDS_2098 "Standardowy joystick 6-przyciskowy" - IDS_2099 "Standardowy joystick 8-przyciskowy" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Żaden" - IDS_2104 "Nie można załadować akceleratorów klawiaturowych." - IDS_2105 "Nie można zarejestrować surowych danych wejściowych." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Dyskietka %i (%s): %ls" - IDS_2109 "Wszystkie obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Zaawansowane obrazy sektorów (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Podstawowe obrazy sektorów (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Obrazy powierzchniowe (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2110 "Nie można zainicjować FreeType" - IDS_2111 "Nie można zainicjować SDL, wymagany SDL2.dll" - IDS_2112 "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" - IDS_2113 "Jesteś pewien że chcesz zakończyć 86Box?" - IDS_2114 "Nie można zainicjować Ghostscript" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2117 "Witamy w 86Box!" - IDS_2118 "Kontroler wewnętrzny" - IDS_2119 "Zakończ" - IDS_2120 "Nie znaleziono obrazów ROM" - IDS_2121 "Czy chcesz zapisać ustawienia?" - IDS_2122 "To spowoduje twardy reset wirtualnej maszyny." - IDS_2123 "Zapisz" - IDS_2124 "O 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Sprawdzaj BPB" + IDS_2089 "KB" + IDS_2090 "Nie można zainicjować renderera wideo." + IDS_2091 "Domyślny" + IDS_2092 "%i Stany oczekiwania" + IDS_2093 "Rodzaj" + IDS_2094 "Nie udało się ustawić PCap" + IDS_2095 "Nie znaleziono urządzeń PCap" + IDS_2096 "Nieprawidłowe urządzenie PCap" + IDS_2097 "Standardowe joysticki 2-przyciskowe" + IDS_2098 "Standardowy joystick 4-przyciskowy" + IDS_2099 "Standardowy joystick 6-przyciskowy" + IDS_2100 "Standardowy joystick 8-przyciskowy" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Żaden" + IDS_2105 "Nie można załadować akceleratorów klawiaturowych." + IDS_2106 "Nie można zarejestrować surowych danych wejściowych." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Dyskietka %i (%s): %ls" + IDS_2110 "Wszystkie obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Zaawansowane obrazy sektorów (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Podstawowe obrazy sektorów (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Obrazy powierzchniowe (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" + IDS_2111 "Nie można zainicjować FreeType" + IDS_2112 "Nie można zainicjować SDL, wymagany SDL2.dll" + IDS_2113 "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" + IDS_2114 "Jesteś pewien że chcesz zakończyć 86Box?" + IDS_2115 "Nie można zainicjować Ghostscript" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" + IDS_2118 "Witamy w 86Box!" + IDS_2119 "Kontroler wewnętrzny" + IDS_2120 "Zakończ" + IDS_2121 "Nie znaleziono obrazów ROM" + IDS_2122 "Czy chcesz zapisać ustawienia?" + IDS_2123 "To spowoduje twardy reset wirtualnej maszyny." + IDS_2124 "Zapisz" + IDS_2125 "O 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "Emulator starych komputerów\n\nAutorzy: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." - IDS_2127 "OK" - IDS_2128 "Sprzęt niedostępny" + IDS_2127 "Emulator starych komputerów\n\nAutorzy: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." + IDS_2128 "OK" + IDS_2129 "Sprzęt niedostępny" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Sprawdź, czy " LIB_NAME_PCAP " jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z " LIB_NAME_PCAP "." - IDS_2130 "Nieprawidłowa konfiguracja" + IDS_2130 "Sprawdź, czy " LIB_NAME_PCAP " jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z " LIB_NAME_PCAP "." + IDS_2131 "Nieprawidłowa konfiguracja" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " jest wymagany do emulacji drukarki ESC-P." + IDS_2132 LIB_NAME_FREETYPE " jest wymagany do emulacji drukarki ESC-P." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." + IDS_2133 LIB_NAME_GS " jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " jest wymagany dla wyjścia FluidSynth MIDI." - IDS_2134 "Przechodzenie do trybu pełnoekranowego" - IDS_2135 "Nie pokazuj więcej tego komunikatu" - IDS_2136 "Nie kończ" - IDS_2137 "Przywróć" - IDS_2138 "Nie przywracaj" - IDS_2139 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2140 "Obrazy CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2141 "Konfiguracja urządzenia %hs" - IDS_2142 "Monitor w trybie czuwania" - IDS_2143 "Shadery OpenGL (*.GLSL)\0*.GLSL\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2144 "Opcje OpenGL" - IDS_2145 "Ładujesz nieobsługiwaną konfigurację" - IDS_2146 "Wybór rodzaju procesora oparty na wybranej maszynie jest wyłączony dla tej emulowanej maszyny.\n\nPozwala to na wybór procesora który jest niekompatybilny z wybraną maszyną. Jednak możesz napotkać niezgodności z BIOS-em maszyny lub innym oprogramowaniem.\n\nAktywacja tego ustawienia nie jest wspierana i każde zgłoszenie błędu może zostać zamknięte jako nieważne." - IDS_2147 "Kontynuuj" - IDS_2148 "Kaseta: %s" - IDS_2149 "Obrazy kaset (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2150 "Kartrydż %i: %ls" - IDS_2151 "Obrazy kartrydżu (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2152 "Błąd inicjalizacji renderera" - IDS_2153 "Nie można zainicjować renderera OpenGL (3.0 Core). Użyj innego." - IDS_2154 "Wznów wykonywanie" - IDS_2155 "Zatrzymaj wykonywanie" - IDS_2156 "Naciśnij Ctrl+Alt+Del" - IDS_2157 "Naciśnij Ctrl+Alt+Esc" - IDS_2158 "Twardy reset" - IDS_2159 "Wyłączenie ACPI" - IDS_2160 "Ustawienia" - IDS_2161 "Wcześniejszy napęd" + IDS_2134 LIB_NAME_FLUIDSYNTH " jest wymagany dla wyjścia FluidSynth MIDI." + IDS_2135 "Przechodzenie do trybu pełnoekranowego" + IDS_2136 "Nie pokazuj więcej tego komunikatu" + IDS_2137 "Nie kończ" + IDS_2138 "Przywróć" + IDS_2139 "Nie przywracaj" + IDS_2140 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" + IDS_2141 "Obrazy CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" + IDS_2142 "Konfiguracja urządzenia %hs" + IDS_2143 "Monitor w trybie czuwania" + IDS_2144 "Shadery OpenGL (*.GLSL)\0*.GLSL\0Wszystkie pliki (*.*)\0*.*\0" + IDS_2145 "Opcje OpenGL" + IDS_2146 "Ładujesz nieobsługiwaną konfigurację" + IDS_2147 "Wybór rodzaju procesora oparty na wybranej maszynie jest wyłączony dla tej emulowanej maszyny.\n\nPozwala to na wybór procesora który jest niekompatybilny z wybraną maszyną. Jednak możesz napotkać niezgodności z BIOS-em maszyny lub innym oprogramowaniem.\n\nAktywacja tego ustawienia nie jest wspierana i każde zgłoszenie błędu może zostać zamknięte jako nieważne." + IDS_2148 "Kontynuuj" + IDS_2149 "Kaseta: %s" + IDS_2150 "Obrazy kaset (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Wszystkie pliki (*.*)\0*.*\0" + IDS_2151 "Kartrydż %i: %ls" + IDS_2152 "Obrazy kartrydżu (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Wszystkie pliki (*.*)\0*.*\0" + IDS_2153 "Błąd inicjalizacji renderera" + IDS_2154 "Nie można zainicjować renderera OpenGL (3.0 Core). Użyj innego." + IDS_2155 "Wznów wykonywanie" + IDS_2156 "Zatrzymaj wykonywanie" + IDS_2157 "Naciśnij Ctrl+Alt+Del" + IDS_2158 "Naciśnij Ctrl+Alt+Esc" + IDS_2159 "Twardy reset" + IDS_2160 "Wyłączenie ACPI" + IDS_2161 "Ustawienia" + IDS_2162 "Wcześniejszy napęd" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index 9c5f65a56..8d16a2a48 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -37,6 +37,7 @@ BEGIN MENUITEM "&Ocultar barra de status", IDM_VID_HIDE_STATUS_BAR MENUITEM "Ocultar &barra de ferramenta", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Mostrar monitores não-primários", IDM_VID_MONITORS MENUITEM "&Janela redimensionável", IDM_VID_RESIZE MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -179,8 +180,8 @@ BEGIN MENUITEM "&Vazio", IDM_CDROM_EMPTY MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Imagem", IDM_CDROM_IMAGE - MENUITEM "&Pasta", IDM_CDROM_DIR + MENUITEM "&Imagem...", IDM_CDROM_IMAGE + MENUITEM "&Pasta...", IDM_CDROM_DIR END END @@ -274,6 +275,7 @@ END #define STR_DYNAREC "Recompilador dinâmico" #define STR_VIDEO "Vídeo:" +#define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "3DFX Voodoo" #define STR_IBM8514 "Gráficos IBM 8514/a" #define STR_XGA "Gráficos XGA" @@ -336,6 +338,7 @@ END #define STR_BUS "Bar.:" #define STR_CHANNEL "Canal:" #define STR_ID "ID:" +#define STR_SPEED "Velocidade:" #define STR_SPECIFY "&Especificar..." #define STR_SECTORS "Setores:" @@ -425,102 +428,103 @@ BEGIN IDS_2084 "CA" IDS_2085 "SE" IDS_2086 "MB" - IDS_2087 "Verificar BPB" - IDS_2088 "KB" - IDS_2089 "Não foi possível inicializar o renderizador de vídeo." - IDS_2090 "Padrão" - IDS_2091 "%i estado(s) de espera" - IDS_2092 "Tipo" - IDS_2093 "Não foi possível configurar o PCap" - IDS_2094 "Nenhum dispositivo PCap encontrado" - IDS_2095 "Dispositivo PCap inválido" - IDS_2096 "Joystick padrão de 2 botões" - IDS_2097 "Joystick padrão de 4 botões" - IDS_2098 "Joystick padrão de 6 botões" - IDS_2099 "Joystick padrão de 8 botões" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Sistema de Controle de Voo Thrustmaster" - IDS_2103 "Nada" - IDS_2104 "Não foi possível carregar os aceleradores do teclado." - IDS_2105 "Não foi possível registrar a entrada bruta." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Disquete %i (%s): %ls" - IDS_2109 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens de setor avançado (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens de setor básico (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os arquivos (*.*)\0*.*\0" - IDS_2110 "Não foi possível inicializar o FreeType" - IDS_2111 "Não é possível inicializar o SDL, é necessário o SDL2.dll" - IDS_2112 "Tem certeza de que deseja reiniciar completamente a máquina emulada?" - IDS_2113 "Tem certeza de que deseja sair do 86Box?" - IDS_2114 "Não é possível inicializar o Ghostscript" - IDS_2115 "Magneto-óptico %i (%ls): %ls" - IDS_2116 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os arquivos (*.*)\0*.*\0" - IDS_2117 "Bem-vindo ao 86Box!" - IDS_2118 "Controlador interno" - IDS_2119 "Sair" - IDS_2120 "Nenhum ROM encontrada" - IDS_2121 "Você deseja salvar as configurações?" - IDS_2122 "Isto fará com que a máquina emulada seja reinicializada." - IDS_2123 "Salvar" - IDS_2124 "Sobre o 86Box" - IDS_2125 "86Box versão" EMU_VERSION + IDS_2087 "Velocidade" + IDS_2088 "Verificar BPB" + IDS_2089 "KB" + IDS_2090 "Não foi possível inicializar o renderizador de vídeo." + IDS_2091 "Padrão" + IDS_2092 "%i estado(s) de espera" + IDS_2093 "Tipo" + IDS_2094 "Não foi possível configurar o PCap" + IDS_2095 "Nenhum dispositivo PCap encontrado" + IDS_2096 "Dispositivo PCap inválido" + IDS_2097 "Joystick padrão de 2 botões" + IDS_2098 "Joystick padrão de 4 botões" + IDS_2099 "Joystick padrão de 6 botões" + IDS_2100 "Joystick padrão de 8 botões" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Sistema de Controle de Voo Thrustmaster" + IDS_2104 "Nada" + IDS_2105 "Não foi possível carregar os aceleradores do teclado." + IDS_2106 "Não foi possível registrar a entrada bruta." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Disquete %i (%s): %ls" + IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens de setor avançado (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens de setor básico (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os arquivos (*.*)\0*.*\0" + IDS_2111 "Não foi possível inicializar o FreeType" + IDS_2112 "Não é possível inicializar o SDL, é necessário o SDL2.dll" + IDS_2113 "Tem certeza de que deseja reiniciar completamente a máquina emulada?" + IDS_2114 "Tem certeza de que deseja sair do 86Box?" + IDS_2115 "Não é possível inicializar o Ghostscript" + IDS_2116 "Magneto-óptico %i (%ls): %ls" + IDS_2117 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os arquivos (*.*)\0*.*\0" + IDS_2118 "Bem-vindo ao 86Box!" + IDS_2119 "Controlador interno" + IDS_2120 "Sair" + IDS_2121 "Nenhum ROM encontrada" + IDS_2122 "Você deseja salvar as configurações?" + IDS_2123 "Isto fará com que a máquina emulada seja reinicializada." + IDS_2124 "Salvar" + IDS_2125 "Sobre o 86Box" + IDS_2126 "86Box versão" EMU_VERSION - IDS_2126 "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." - IDS_2127 "OK" - IDS_2128 "Hardware não disponível" + IDS_2127 "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." + IDS_2128 "OK" + IDS_2129 "Hardware não disponível" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Certifique-se de que " LIB_NAME_PCAP " esteja instalado e que você tenha uma conexão de rede compatível com " LIB_NAME_PCAP "." - IDS_2130 "Configuração inválida" + IDS_2130 "Certifique-se de que " LIB_NAME_PCAP " esteja instalado e que você tenha uma conexão de rede compatível com " LIB_NAME_PCAP "." + IDS_2131 "Configuração inválida" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " é necessário para emulação de impressora ESC/P." + IDS_2132 LIB_NAME_FREETYPE " é necessário para emulação de impressora ESC/P." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." + IDS_2133 LIB_NAME_GS " é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " é necessário para a saída MIDI FluidSynth." - IDS_2134 "Entrando no modo de tela cheia" - IDS_2135 "Não exibir esta mensagem novamente" - IDS_2136 "Não sair" - IDS_2137 "Reiniciar" - IDS_2138 "Não reiniciar" - IDS_2139 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os arquivos (*.*)\0*.*\0" - IDS_2140 "Imagens de CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Todos os arquivos (*.*)\0*.*\0" - IDS_2141 "Configuração do dispositivo %hs" - IDS_2142 "Monitor em modo de suspensão" - IDS_2143 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Todos os arquivos (*.*)\0*.*\0" - IDS_2144 "Opções do OpenGL" - IDS_2145 "Você está carregando uma configuração não suportada" - IDS_2146 "A filtragem do tipo CPU baseada na máquina selecionada é desativada para esta máquina emulada.\n\nIsto torna possível escolher uma CPU que de outra forma seria incompatível com a máquina selecionada. Entretanto, você pode encontrar incompatibilidades com a BIOS da máquina ou outro software.\n\nA ativação desta configuração não é oficialmente suportada e qualquer relatório de erro arquivado pode ser fechado como inválido." - IDS_2147 "Continuar" - IDS_2148 "Cassete: %s" - IDS_2149 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os arquivos (*.*)\0*.*\0" - IDS_2150 "Cartucho %i: %ls" - IDS_2151 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os arquivos (*.*)\0*.*\0" - IDS_2152 "Erro ao inicializar o renderizador" - IDS_2153 "O renderizador OpenGL (Núcleo 3.0) não pôde ser inicializado. Use outro renderizador." - IDS_2154 "Continuar a execução" - IDS_2155 "Pausar a execução" - IDS_2156 "Pressionar Ctrl+Alt+Del" - IDS_2157 "Pressionar Ctrl+Alt+Esc" - IDS_2158 "Reinicialização completa" - IDS_2159 "Desligamento por ACPI" - IDS_2160 "Configurações" - IDS_2161 "Unidade anterior" + IDS_2134 LIB_NAME_FLUIDSYNTH " é necessário para a saída MIDI FluidSynth." + IDS_2135 "Entrando no modo de tela cheia" + IDS_2136 "Não exibir esta mensagem novamente" + IDS_2137 "Não sair" + IDS_2138 "Reiniciar" + IDS_2139 "Não reiniciar" + IDS_2140 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os arquivos (*.*)\0*.*\0" + IDS_2141 "Imagens de CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Todos os arquivos (*.*)\0*.*\0" + IDS_2142 "Configuração do dispositivo %hs" + IDS_2143 "Monitor em modo de suspensão" + IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Todos os arquivos (*.*)\0*.*\0" + IDS_2145 "Opções do OpenGL" + IDS_2146 "Você está carregando uma configuração não suportada" + IDS_2147 "A filtragem do tipo CPU baseada na máquina selecionada é desativada para esta máquina emulada.\n\nIsto torna possível escolher uma CPU que de outra forma seria incompatível com a máquina selecionada. Entretanto, você pode encontrar incompatibilidades com a BIOS da máquina ou outro software.\n\nA ativação desta configuração não é oficialmente suportada e qualquer relatório de erro arquivado pode ser fechado como inválido." + IDS_2148 "Continuar" + IDS_2149 "Cassete: %s" + IDS_2150 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os arquivos (*.*)\0*.*\0" + IDS_2151 "Cartucho %i: %ls" + IDS_2152 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os arquivos (*.*)\0*.*\0" + IDS_2153 "Erro ao inicializar o renderizador" + IDS_2154 "O renderizador OpenGL (Núcleo 3.0) não pôde ser inicializado. Use outro renderizador." + IDS_2155 "Continuar a execução" + IDS_2156 "Pausar a execução" + IDS_2157 "Pressionar Ctrl+Alt+Del" + IDS_2158 "Pressionar Ctrl+Alt+Esc" + IDS_2159 "Reinicialização completa" + IDS_2160 "Desligamento por ACPI" + IDS_2161 "Configurações" + IDS_2162 "Unidade anterior" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc index 55b81c8d3..704262b3d 100644 --- a/src/win/languages/pt-PT.rc +++ b/src/win/languages/pt-PT.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Janela redimensionável", IDM_VID_RESIZE MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "&CDROM vazio", IDM_CDROM_EMPTY MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Imagem", IDM_CDROM_IMAGE - MENUITEM "&Pasta", IDM_CDROM_DIR + MENUITEM "&Imagem...", IDM_CDROM_IMAGE + MENUITEM "&Pasta...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Recompilador dinâmico" #define STR_VIDEO "Vídeo:" +#define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "Gráficos Voodoo" #define STR_IBM8514 "Gráficos IBM 8514/a" #define STR_XGA "Gráficos XGA" @@ -333,6 +335,7 @@ END #define STR_BUS "Barram.:" #define STR_CHANNEL "Canal:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Especificar..." #define STR_SECTORS "Sectores:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "C" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Verificar BPB" - IDS_2088 "KB" - IDS_2089 "Não foi possível inicializar o renderizador vídeo." - IDS_2090 "Padrão" - IDS_2091 "%i estado(s) de espera" - IDS_2092 "Tipo" - IDS_2093 "Falha na configuração de PCap" - IDS_2094 "Não foi encontrado um dispositivo PCap" - IDS_2095 "Dispositivo PCap inválido" - IDS_2096 "Joystick(s) standard de 2 botões" - IDS_2097 "Joystick(s) standard de 4 botões" - IDS_2098 "Joystick(s) standard de 6 botões" - IDS_2099 "Joystick(s) standard de 8 botões" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Nenhum" - IDS_2104 "Não foi possível inicializar os aceleradores de teclado." - IDS_2105 "Não foi possível registar a entrada bruta." - IDS_2106 "%u" - IDS_2107 "%u MB (CCS: %i, %i, %i)" - IDS_2108 "Disquete %i (%s): %ls" - IDS_2109 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens avançadas de sector (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens básicas de sector (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2110 "Não foi possível inicializar o FreeType" - IDS_2111 "Não foi possível inicializar o SDL. O ficheiro SDL2.dll é necessário!" - IDS_2112 "Tem a certeza de que quer um reinício completo da máquina emulada?" - IDS_2113 "Tem a certeza de que quer sair do 86Box?" - IDS_2114 "Não foi possível inicializar o Ghostscript" - IDS_2115 "Magneto-óptico %i (%ls): %ls" - IDS_2116 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todas as imagens (*.*)\0*.*\0" - IDS_2117 "Bem-vindos ao 86Box!" - IDS_2118 "Controlador interno" - IDS_2119 "Sair" - IDS_2120 "Não foi encontrada nenhuma ROM" - IDS_2121 "Deseja guardar as definições?" - IDS_2122 "Isto irá causar um reinício completo da máquina emulada." - IDS_2123 "Guardar" - IDS_2124 "Acerca do 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Verificar BPB" + IDS_2089 "KB" + IDS_2090 "Não foi possível inicializar o renderizador vídeo." + IDS_2091 "Padrão" + IDS_2092 "%i estado(s) de espera" + IDS_2093 "Tipo" + IDS_2094 "Falha na configuração de PCap" + IDS_2095 "Não foi encontrado um dispositivo PCap" + IDS_2096 "Dispositivo PCap inválido" + IDS_2097 "Joystick(s) standard de 2 botões" + IDS_2098 "Joystick(s) standard de 4 botões" + IDS_2099 "Joystick(s) standard de 6 botões" + IDS_2100 "Joystick(s) standard de 8 botões" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Nenhum" + IDS_2105 "Não foi possível inicializar os aceleradores de teclado." + IDS_2106 "Não foi possível registar a entrada bruta." + IDS_2107 "%u" + IDS_2108 "%u MB (CCS: %i, %i, %i)" + IDS_2109 "Disquete %i (%s): %ls" + IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens avançadas de sector (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens básicas de sector (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os ficheiros (*.*)\0*.*\0" + IDS_2111 "Não foi possível inicializar o FreeType" + IDS_2112 "Não foi possível inicializar o SDL. O ficheiro SDL2.dll é necessário!" + IDS_2113 "Tem a certeza de que quer um reinício completo da máquina emulada?" + IDS_2114 "Tem a certeza de que quer sair do 86Box?" + IDS_2115 "Não foi possível inicializar o Ghostscript" + IDS_2116 "Magneto-óptico %i (%ls): %ls" + IDS_2117 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todas as imagens (*.*)\0*.*\0" + IDS_2118 "Bem-vindos ao 86Box!" + IDS_2119 "Controlador interno" + IDS_2120 "Sair" + IDS_2121 "Não foi encontrada nenhuma ROM" + IDS_2122 "Deseja guardar as definições?" + IDS_2123 "Isto irá causar um reinício completo da máquina emulada." + IDS_2124 "Guardar" + IDS_2125 "Acerca do 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." - IDS_2127 "OK" - IDS_2128 "Hardware não disponível" + IDS_2127 "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." + IDS_2128 "OK" + IDS_2129 "Hardware não disponível" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Certifique-se de que a biblioteca " LIB_NAME_PCAP " está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca " LIB_NAME_PCAP "." - IDS_2130 "Configuração inválida" + IDS_2130 "Certifique-se de que a biblioteca " LIB_NAME_PCAP " está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca " LIB_NAME_PCAP "." + IDS_2131 "Configuração inválida" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " é requerida para a emulação de impressora ESC/P." + IDS_2132 LIB_NAME_FREETYPE " é requerida para a emulação de impressora ESC/P." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." + IDS_2133 LIB_NAME_GS " é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " é necessário para a saída MIDI FluidSynth MIDI." - IDS_2134 "A entrar no modo de ecrã cheio" - IDS_2135 "Não mostrar mais esta mensagem" - IDS_2136 "Não sair" - IDS_2137 "Reiniciar" - IDS_2138 "Não reiniciar" - IDS_2139 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2140 "Imagens CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2141 "Configuração de dispositivo %hs" - IDS_2142 "Ecrã em modo de sono" - IDS_2143 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2144 "Opções de OpenGL" - IDS_2145 "Está a carregar uma configuração sem suporte!" - IDS_2146 "A filtragem do tipo de CPU baseada na máquina escolhida está desativada para esta máquina emulada.\n\nIsto torna possível escolher um CPU que, de outra forma, não seria compatível com a máquina escolhida. No entanto, pode não ser compatível com a BIOS da máquina ou outros programas.\n\nA activação desta definição não tem suporte oficial e qualquer relatório de erros pode ser fechado como inválido." - IDS_2147 "Continuar" - IDS_2148 "Cassete: %s" - IDS_2149 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2150 "Cartucho %i: %ls" - IDS_2151 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2152 "Erro na inicialização do renderizador" - IDS_2153 "Não foi possível inicializar o renderizador OpenGL (3.0 Core). Utilize outro renderizador." - IDS_2154 "Retomar execução" - IDS_2155 "Pausar execução" - IDS_2156 "Ctrl+Alt+Del" - IDS_2157 "Ctrl+Alt+Esc" - IDS_2158 "Reinicialização completa" - IDS_2159 "Encerramento ACPI" - IDS_2160 "Definições" - IDS_2161 "Unidade anterior" + IDS_2134 LIB_NAME_FLUIDSYNTH " é necessário para a saída MIDI FluidSynth MIDI." + IDS_2135 "A entrar no modo de ecrã cheio" + IDS_2136 "Não mostrar mais esta mensagem" + IDS_2137 "Não sair" + IDS_2138 "Reiniciar" + IDS_2139 "Não reiniciar" + IDS_2140 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os ficheiros (*.*)\0*.*\0" + IDS_2141 "Imagens CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Todos os ficheiros (*.*)\0*.*\0" + IDS_2142 "Configuração de dispositivo %hs" + IDS_2143 "Ecrã em modo de sono" + IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Todos os ficheiros (*.*)\0*.*\0" + IDS_2145 "Opções de OpenGL" + IDS_2146 "Está a carregar uma configuração sem suporte!" + IDS_2147 "A filtragem do tipo de CPU baseada na máquina escolhida está desativada para esta máquina emulada.\n\nIsto torna possível escolher um CPU que, de outra forma, não seria compatível com a máquina escolhida. No entanto, pode não ser compatível com a BIOS da máquina ou outros programas.\n\nA activação desta definição não tem suporte oficial e qualquer relatório de erros pode ser fechado como inválido." + IDS_2148 "Continuar" + IDS_2149 "Cassete: %s" + IDS_2150 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os ficheiros (*.*)\0*.*\0" + IDS_2151 "Cartucho %i: %ls" + IDS_2152 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os ficheiros (*.*)\0*.*\0" + IDS_2153 "Erro na inicialização do renderizador" + IDS_2154 "Não foi possível inicializar o renderizador OpenGL (3.0 Core). Utilize outro renderizador." + IDS_2155 "Retomar execução" + IDS_2156 "Pausar execução" + IDS_2157 "Ctrl+Alt+Del" + IDS_2158 "Ctrl+Alt+Esc" + IDS_2159 "Reinicialização completa" + IDS_2160 "Encerramento ACPI" + IDS_2161 "Definições" + IDS_2162 "Unidade anterior" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index 95b550dce..667cfafa6 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Скрыть строку состояния", IDM_VID_HIDE_STATUS_BAR MENUITEM "С&крыть панель инструментов", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Изменяемый размер окна", IDM_VID_RESIZE MENUITEM "&Запомнить размер и положение", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -177,7 +178,7 @@ BEGIN MENUITEM "&Снова загрузить предыдущий образ", IDM_CDROM_RELOAD MENUITEM SEPARATOR MENUITEM "&Образ...", IDM_CDROM_IMAGE - MENUITEM "&Папка", IDM_CDROM_DIR + MENUITEM "&Папка...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Динамический рекомпилятор" #define STR_VIDEO "Видеокарта:" +#define STR_VIDEO_2 "Видеокарта 2:" #define STR_VOODOO "Ускоритель Voodoo" #define STR_IBM8514 "Ускоритель IBM 8514/a" #define STR_XGA "Ускоритель XGA" @@ -333,6 +335,7 @@ END #define STR_BUS "Шина:" #define STR_CHANNEL "Канал:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Указать..." #define STR_SECTORS "Сектора:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "МБ" - IDS_2087 "Проверять BPB" - IDS_2088 "КБ" - IDS_2089 "Не удалось инициализировать рендерер видео." - IDS_2090 "По умолчанию" - IDS_2091 "%i WS" - IDS_2092 "Тип" - IDS_2093 "Не удалось настроить PCap" - IDS_2094 "Устройства PCap не найдены" - IDS_2095 "Неверное устройство PCap" - IDS_2096 "Стандартный 2-кнопочный джойстик" - IDS_2097 "Стандартный 4-кнопочный джойстик" - IDS_2098 "Стандартный 6-кнопочный джойстик" - IDS_2099 "Стандартный 8-кнопочный джойстик" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Система управления полетом Thrustmaster" - IDS_2103 "Нет" - IDS_2104 "Невозможно загрузить ускорители клавиатуры." - IDS_2105 "Невозможно зарегистрировать необработанный (RAW) ввод." - IDS_2106 "%u" - IDS_2107 "%u МБ (CHS: %i, %i, %i)" - IDS_2108 "Дисковод %i (%s): %ls" - IDS_2109 "Все образы (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Расширенные образы секторов (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основные образы секторов (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образы Flux (*.FDI)\0*.FDI\0Образы Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Все файлы (*.*)\0*.*\0" - IDS_2110 "Невозможно инициализировать FreeType" - IDS_2111 "Невозможно инициализировать SDL, требуется SDL2.dll" - IDS_2112 "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" - IDS_2113 "Вы уверены, что хотите выйти из 86Box?" - IDS_2114 "Невозможно инициализировать Ghostscript" - IDS_2115 "Магнитооптический %i (%ls): %ls" - IDS_2116 "Образы магнитооптических дисков (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" - IDS_2117 "Добро пожаловать в 86Box!" - IDS_2118 "Встроенный контроллер" - IDS_2119 "Выход" - IDS_2120 "ПЗУ не найдены" - IDS_2121 "Хотите ли вы сохранить настройки?" - IDS_2122 "Это приведет к холодной перезагрузке эмулируемой машины." - IDS_2123 "Сохранить" - IDS_2124 "О 86Box" - IDS_2125 "86Box v." EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Проверять BPB" + IDS_2089 "КБ" + IDS_2090 "Не удалось инициализировать рендерер видео." + IDS_2091 "По умолчанию" + IDS_2092 "%i WS" + IDS_2093 "Тип" + IDS_2094 "Не удалось настроить PCap" + IDS_2095 "Устройства PCap не найдены" + IDS_2096 "Неверное устройство PCap" + IDS_2097 "Стандартный 2-кнопочный джойстик" + IDS_2098 "Стандартный 4-кнопочный джойстик" + IDS_2099 "Стандартный 6-кнопочный джойстик" + IDS_2100 "Стандартный 8-кнопочный джойстик" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Система управления полетом Thrustmaster" + IDS_2104 "Нет" + IDS_2105 "Невозможно загрузить ускорители клавиатуры." + IDS_2106 "Невозможно зарегистрировать необработанный (RAW) ввод." + IDS_2107 "%u" + IDS_2108 "%u МБ (CHS: %i, %i, %i)" + IDS_2109 "Дисковод %i (%s): %ls" + IDS_2110 "Все образы (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Расширенные образы секторов (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основные образы секторов (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образы Flux (*.FDI)\0*.FDI\0Образы Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Все файлы (*.*)\0*.*\0" + IDS_2111 "Невозможно инициализировать FreeType" + IDS_2112 "Невозможно инициализировать SDL, требуется SDL2.dll" + IDS_2113 "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" + IDS_2114 "Вы уверены, что хотите выйти из 86Box?" + IDS_2115 "Невозможно инициализировать Ghostscript" + IDS_2116 "Магнитооптический %i (%ls): %ls" + IDS_2117 "Образы магнитооптических дисков (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" + IDS_2118 "Добро пожаловать в 86Box!" + IDS_2119 "Встроенный контроллер" + IDS_2120 "Выход" + IDS_2121 "ПЗУ не найдены" + IDS_2122 "Хотите ли вы сохранить настройки?" + IDS_2123 "Это приведет к холодной перезагрузке эмулируемой машины." + IDS_2124 "Сохранить" + IDS_2125 "О 86Box" + IDS_2126 "86Box v." EMU_VERSION - IDS_2126 "Эмулятор старых компьютеров\n\nАвторы: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." - IDS_2127 "OK" - IDS_2128 "Оборудование недоступно" + IDS_2127 "Эмулятор старых компьютеров\n\nАвторы: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." + IDS_2128 "OK" + IDS_2129 "Оборудование недоступно" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Убедитесь, что " LIB_NAME_PCAP " установлен и ваше сетевое соединение, совместимо с " LIB_NAME_PCAP "." - IDS_2130 "Недопустимая конфигурация" + IDS_2130 "Убедитесь, что " LIB_NAME_PCAP " установлен и ваше сетевое соединение, совместимо с " LIB_NAME_PCAP "." + IDS_2131 "Недопустимая конфигурация" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 "Для эмуляции принтера ESC/P требуется " LIB_NAME_FREETYPE "." + IDS_2132 "Для эмуляции принтера ESC/P требуется " LIB_NAME_FREETYPE "." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " требуется для автоматического преобразования файлов PostScript в PDF.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." + IDS_2133 LIB_NAME_GS " требуется для автоматического преобразования файлов PostScript в PDF.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 "Для FluidSynth MIDI-вывода требуется " LIB_NAME_FLUIDSYNTH "." - IDS_2134 "Вход в полноэкранный режим" - IDS_2135 "Больше не показывать это сообщение" - IDS_2136 "Не выходить" - IDS_2137 "Перезагрузить" - IDS_2138 "Не перезагружать" - IDS_2139 "Образы магнитооптических дисков (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" - IDS_2140 "Образы CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Все файлы (*.*)\0*.*\0" - IDS_2141 "Конфигурация устройства %hs" - IDS_2142 "Монитор в спящем режиме" - IDS_2143 "Шейдеры OpenGL (*.GLSL)\0*.GLSL\0Все файлы (*.*)\0*.*\0" - IDS_2144 "Параметры OpenGL" - IDS_2145 "Вы загружаете неподдерживаемую конфигурацию" - IDS_2146 "Выбор типов ЦП для этой системной платы на данной эмулируемой машине отключен.\n\nЭто позволяет выбрать процессор, который в противном случае несовместим с выбранной материнской платой. Однако, вы можете столкнуться с несовместимостью с BIOS материнской платы или другим ПО.\n\nВключение этого параметра официально не поддерживается, и все поданные отчеты об ошибках могут быть закрыты как недействительные." - IDS_2147 "Продолжить" - IDS_2148 "Кассета: %s" - IDS_2149 "Образы кассет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Все файлы (*.*)\0*.*\0" - IDS_2150 "Картридж %i: %ls" - IDS_2151 "Образы картриджей (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Все файлы (*.*)\0*.*\0" - IDS_2152 "Ошибка инициализации рендерера" - IDS_2153 "Невозможно инициализировать рендерер OpenGL (3.0). Пожалуйста, используйте другой рендерер." - IDS_2154 "Возобновить выполнение" - IDS_2155 "Приостановить выполнение" - IDS_2156 "Нажать Ctrl+Alt+Del" - IDS_2157 "Нажать Ctrl+Alt+Esc" - IDS_2158 "Холодная перезагрузка" - IDS_2159 "Сигнал завершения ACPI" - IDS_2160 "Настройки машины" - IDS_2161 "Предыдущий дисковод" + IDS_2134 "Для FluidSynth MIDI-вывода требуется " LIB_NAME_FLUIDSYNTH "." + IDS_2135 "Вход в полноэкранный режим" + IDS_2136 "Больше не показывать это сообщение" + IDS_2137 "Не выходить" + IDS_2138 "Перезагрузить" + IDS_2139 "Не перезагружать" + IDS_2140 "Образы магнитооптических дисков (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" + IDS_2141 "Образы CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Все файлы (*.*)\0*.*\0" + IDS_2142 "Конфигурация устройства %hs" + IDS_2143 "Монитор в спящем режиме" + IDS_2144 "Шейдеры OpenGL (*.GLSL)\0*.GLSL\0Все файлы (*.*)\0*.*\0" + IDS_2145 "Параметры OpenGL" + IDS_2146 "Вы загружаете неподдерживаемую конфигурацию" + IDS_2147 "Выбор типов ЦП для этой системной платы на данной эмулируемой машине отключен.\n\nЭто позволяет выбрать процессор, который в противном случае несовместим с выбранной материнской платой. Однако, вы можете столкнуться с несовместимостью с BIOS материнской платы или другим ПО.\n\nВключение этого параметра официально не поддерживается, и все поданные отчеты об ошибках могут быть закрыты как недействительные." + IDS_2148 "Продолжить" + IDS_2149 "Кассета: %s" + IDS_2150 "Образы кассет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Все файлы (*.*)\0*.*\0" + IDS_2151 "Картридж %i: %ls" + IDS_2152 "Образы картриджей (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Все файлы (*.*)\0*.*\0" + IDS_2153 "Ошибка инициализации рендерера" + IDS_2154 "Невозможно инициализировать рендерер OpenGL (3.0). Пожалуйста, используйте другой рендерер." + IDS_2155 "Возобновить выполнение" + IDS_2156 "Приостановить выполнение" + IDS_2157 "Нажать Ctrl+Alt+Del" + IDS_2158 "Нажать Ctrl+Alt+Esc" + IDS_2159 "Холодная перезагрузка" + IDS_2160 "Сигнал завершения ACPI" + IDS_2161 "Настройки машины" + IDS_2162 "Предыдущий дисковод" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc index 7b957cf0d..3bdf357f4 100644 --- a/src/win/languages/sl-SI.rc +++ b/src/win/languages/sl-SI.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Skrij statusno vrstico", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "S&premenljiva velikost okna", IDM_VID_RESIZE MENUITEM "&Zapomni si velikost in položaj", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "&Prazen", IDM_CDROM_EMPTY MENUITEM "&Naloži zadnjo sliko", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Slika", IDM_CDROM_IMAGE - MENUITEM "&Mapa", IDM_CDROM_DIR + MENUITEM "&Slika...", IDM_CDROM_IMAGE + MENUITEM "&Mapa...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Dinamični prevajalnik" #define STR_VIDEO "Video:" +#define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo grafika" #define STR_IBM8514 "IBM 8514/a grafika" #define STR_XGA "XGA grafika" @@ -333,6 +335,7 @@ END #define STR_BUS "Vodilo:" #define STR_CHANNEL "Kanal:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "Določi..." #define STR_SECTORS "Sektorji:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Preveri BPB" - IDS_2088 "KB" - IDS_2089 "Ne morem inicializirati pogona upodabljanja." - IDS_2090 "Privzeto" - IDS_2091 "%i stanj čakanja" - IDS_2092 "Vrsta" - IDS_2093 "Nastavitev PCap ni uspela" - IDS_2094 "Nobena naprava PCap ni bila najdena" - IDS_2095 "Neveljavna naprava PCap" - IDS_2096 "Standardna krmilna palica z 2 gumboma" - IDS_2097 "Standardna krmilna palica s 4 gumbi" - IDS_2098 "Standardna krmilna palica s 6 gumbi" - IDS_2099 "Standardna krmilna palica z 8 gumbi" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "Brez" - IDS_2104 "Ne morem naložiti pospeševalnikov tipkovnice." - IDS_2105 "Ne morem registrirati neobdelanega vnosa." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Disketa %i (%s): %ls" - IDS_2109 "Vse slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Tokovne slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Vse datoteke (*.*)\0*.*\0" - IDS_2110 "Ne morem inicializirati FreeType" - IDS_2111 "Ne morem inicializirati SDL, potrebna je knjižica SDL2.dll" - IDS_2112 "Ste prepričani, da želite ponovno zagnati emulirani sistem?" - IDS_2113 "Ste prepričani, da želite zapreti 86Box?" - IDS_2114 "Ne morem inicializirati Ghostscript" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "Slike MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Vse datoteke (*.*)\0*.*\0" - IDS_2117 "Dobrodošli v 86Box!" - IDS_2118 "Notranji krmilnik" - IDS_2119 "Izhod" - IDS_2120 "Nobeni ROM-i niso bili najdeni" - IDS_2121 "Želite shraniti nastavitve?" - IDS_2122 "To bo ponovno zagnalo emuliran sistem." - IDS_2123 "Shrani" - IDS_2124 "O programu 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Preveri BPB" + IDS_2089 "KB" + IDS_2090 "Ne morem inicializirati pogona upodabljanja." + IDS_2091 "Privzeto" + IDS_2092 "%i stanj čakanja" + IDS_2093 "Vrsta" + IDS_2094 "Nastavitev PCap ni uspela" + IDS_2095 "Nobena naprava PCap ni bila najdena" + IDS_2096 "Neveljavna naprava PCap" + IDS_2097 "Standardna krmilna palica z 2 gumboma" + IDS_2098 "Standardna krmilna palica s 4 gumbi" + IDS_2099 "Standardna krmilna palica s 6 gumbi" + IDS_2100 "Standardna krmilna palica z 8 gumbi" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "Brez" + IDS_2105 "Ne morem naložiti pospeševalnikov tipkovnice." + IDS_2106 "Ne morem registrirati neobdelanega vnosa." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Disketa %i (%s): %ls" + IDS_2110 "Vse slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Tokovne slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Vse datoteke (*.*)\0*.*\0" + IDS_2111 "Ne morem inicializirati FreeType" + IDS_2112 "Ne morem inicializirati SDL, potrebna je knjižica SDL2.dll" + IDS_2113 "Ste prepričani, da želite ponovno zagnati emulirani sistem?" + IDS_2114 "Ste prepričani, da želite zapreti 86Box?" + IDS_2115 "Ne morem inicializirati Ghostscript" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "Slike MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Vse datoteke (*.*)\0*.*\0" + IDS_2118 "Dobrodošli v 86Box!" + IDS_2119 "Notranji krmilnik" + IDS_2120 "Izhod" + IDS_2121 "Nobeni ROM-i niso bili najdeni" + IDS_2122 "Želite shraniti nastavitve?" + IDS_2123 "To bo ponovno zagnalo emuliran sistem." + IDS_2124 "Shrani" + IDS_2125 "O programu 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "Emulator starih računalnikov\n\nAvtorji: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." - IDS_2127 "V redu" - IDS_2128 "Strojna oprema ni na voljo" + IDS_2127 "Emulator starih računalnikov\n\nAvtorji: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." + IDS_2128 "V redu" + IDS_2129 "Strojna oprema ni na voljo" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Prepičajte se, da je nameščen " LIB_NAME_PCAP " in da ste na omrežni povezavi, združljivi z " LIB_NAME_PCAP - IDS_2130 "Neveljavna konfiguracija" + IDS_2130 "Prepičajte se, da je nameščen " LIB_NAME_PCAP " in da ste na omrežni povezavi, združljivi z " LIB_NAME_PCAP + IDS_2131 "Neveljavna konfiguracija" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " je potreben za emuliranje ESC/P tiskalnika." + IDS_2132 LIB_NAME_FREETYPE " je potreben za emuliranje ESC/P tiskalnika." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." + IDS_2133 LIB_NAME_GS " je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " je potreben za FluidSynth MIDI izhod." - IDS_2134 "Preklapljam v celozaslonski način" - IDS_2135 "Ne pokaži več tega sporočila" - IDS_2136 "Prekliči izhod" - IDS_2137 "Resetiraj" - IDS_2138 "Ne resetiraj" - IDS_2139 "Slike MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Vse datoteke (*.*)\0*.*\0" - IDS_2140 "Slike CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Vse datoteke (*.*)\0*.*\0" - IDS_2141 "Konfiguracija naprave %hs" - IDS_2142 "Zaslon v načinu spanja" - IDS_2143 "Senčilniki OpenGL (*.GLSL)\0*.GLSL\0Vse datoteke (*.*)\0*.*\0" - IDS_2144 "Možnosti OpenGL" - IDS_2145 "Nalagate nepodprto konfiguracijo" - IDS_2146 "Filtriranje vrste procesorja glede na izbran sistem je onemogočeno za ta emuliran sistem.\n\nTako lahko izberete procesor, ki je sicer nezdružljiv z izbranim sistemom. Vendar lahko naletite na nezdružljivosti z BIOS-om sistema ali drugo programsko opremo\n\nOmogočanje te nastavitve ni uradno podprto, vsa poročila o hroščih iz tega naslova pa bodo zaprta kot neveljavna." - IDS_2147 "Nadaljuj" - IDS_2148 "Kaseta: %s" - IDS_2149 "Slike kaset (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Vse datoteke (*.*)\0*.*\0" - IDS_2150 "Spominski vložek %i: %ls" - IDS_2151 "Slike spominskega vložka (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Vse datoteke (*.*)\0*.*\0" - IDS_2152 "Napaka pri zagonu sistema za upodabljanje" - IDS_2153 "Sistema za upodabljanje OpenGL (3.0 Core) ni bilo mogoče zagnati. Uporabite drug sistem za upodabljanje." - IDS_2154 "Nadaljuj izvajanje" - IDS_2155 "Prekini izvajanje" - IDS_2156 "Press Ctrl+Alt+Del" - IDS_2157 "Press Ctrl+Alt+Esc" - IDS_2158 "Ponovni zagon" - IDS_2159 "Zaustavitev ACPI" - IDS_2160 "Nastavitve" - IDS_2161 "Zgodnejši pogon" + IDS_2134 LIB_NAME_FLUIDSYNTH " je potreben za FluidSynth MIDI izhod." + IDS_2135 "Preklapljam v celozaslonski način" + IDS_2136 "Ne pokaži več tega sporočila" + IDS_2137 "Prekliči izhod" + IDS_2138 "Resetiraj" + IDS_2139 "Ne resetiraj" + IDS_2140 "Slike MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Vse datoteke (*.*)\0*.*\0" + IDS_2141 "Slike CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Vse datoteke (*.*)\0*.*\0" + IDS_2142 "Konfiguracija naprave %hs" + IDS_2143 "Zaslon v načinu spanja" + IDS_2144 "Senčilniki OpenGL (*.GLSL)\0*.GLSL\0Vse datoteke (*.*)\0*.*\0" + IDS_2145 "Možnosti OpenGL" + IDS_2146 "Nalagate nepodprto konfiguracijo" + IDS_2147 "Filtriranje vrste procesorja glede na izbran sistem je onemogočeno za ta emuliran sistem.\n\nTako lahko izberete procesor, ki je sicer nezdružljiv z izbranim sistemom. Vendar lahko naletite na nezdružljivosti z BIOS-om sistema ali drugo programsko opremo\n\nOmogočanje te nastavitve ni uradno podprto, vsa poročila o hroščih iz tega naslova pa bodo zaprta kot neveljavna." + IDS_2148 "Nadaljuj" + IDS_2149 "Kaseta: %s" + IDS_2150 "Slike kaset (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Vse datoteke (*.*)\0*.*\0" + IDS_2151 "Spominski vložek %i: %ls" + IDS_2152 "Slike spominskega vložka (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Vse datoteke (*.*)\0*.*\0" + IDS_2153 "Napaka pri zagonu sistema za upodabljanje" + IDS_2154 "Sistema za upodabljanje OpenGL (3.0 Core) ni bilo mogoče zagnati. Uporabite drug sistem za upodabljanje." + IDS_2155 "Nadaljuj izvajanje" + IDS_2156 "Prekini izvajanje" + IDS_2157 "Press Ctrl+Alt+Del" + IDS_2158 "Press Ctrl+Alt+Esc" + IDS_2159 "Ponovni zagon" + IDS_2160 "Zaustavitev ACPI" + IDS_2161 "Nastavitve" + IDS_2162 "Zgodnejši pogon" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc index 4578dc771..858bf0a01 100644 --- a/src/win/languages/tr-TR.rc +++ b/src/win/languages/tr-TR.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Durum çubuğunu gizle", IDM_VID_HIDE_STATUS_BAR MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Yeniden boyutlandırılabilir pencere", IDM_VID_RESIZE MENUITEM "&Pencere boyut ve pozisyonunu hatırla", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "İmajı &çıkar", IDM_CDROM_EMPTY MENUITEM "&Önceki imajı seç", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&İmaj seç", IDM_CDROM_IMAGE - MENUITEM "&Klasör", IDM_CDROM_DIR + MENUITEM "&İmaj seç...", IDM_CDROM_IMAGE + MENUITEM "&Klasör...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Dinamik Derleyici" #define STR_VIDEO "Ekran kartı:" +#define STR_VIDEO_2 "Ekran kartı 2:" #define STR_VOODOO "Voodoo Grafikleri" #define STR_IBM8514 "IBM 8514/a Grafikleri" #define STR_XGA "XGA Grafikleri" @@ -333,6 +335,7 @@ END #define STR_BUS "Veri yolu:" #define STR_CHANNEL "Kanal:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Belirle..." #define STR_SECTORS "Sektörler:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "BPB'yi kontrol et" - IDS_2088 "KB" - IDS_2089 "Video işleyici başlatılamadı." - IDS_2090 "Varsayılan" - IDS_2091 "%i Bekleme durumları" - IDS_2092 "Tür" - IDS_2093 "PCap ayarlanamadı" - IDS_2094 "Herhangi bir PCap cihazı bulunamadı" - IDS_2095 "Geçersiz PCap cihazı" - IDS_2096 "Standart 2-button oyun kolları" - IDS_2097 "Standart 4-button oyun kolu" - IDS_2098 "Standart 6-button oyun kolu" - IDS_2099 "Standart 8-button oyun kolu" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Kontrol Sistemi" - IDS_2103 "Hiçbiri" - IDS_2104 "Klavye ivdirgeçleri yüklenemedi." - IDS_2105 "Ham girdi kaydedilemedi." - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "Disket %i (%s): %ls" - IDS_2109 "Tüm imajlar (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Gelişmiş sektör imajları (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basit sektör imajları (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Yüzey imajları (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2110 "FreeType başlatılamadı" - IDS_2111 "SDL başlatılamadı, SDL2.dll gerekmektedir" - IDS_2112 "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" - IDS_2113 "86Box'tan çıkmak istediğinize emin misiniz?" - IDS_2114 "Ghostscript başlatılamadı" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "MO imajları (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2117 "86Box'a hoşgeldiniz!" - IDS_2118 "Dahili kontrolcü" - IDS_2119 "Çıkış" - IDS_2120 "Hiçbir ROM imajı bulunamadı" - IDS_2121 "Ayarları kaydetmek istediğinizden emin misiniz?" - IDS_2122 "Bu makineyi yeniden başlatacak." - IDS_2123 "Kaydet" - IDS_2124 "86Box Hakkında" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "BPB'yi kontrol et" + IDS_2089 "KB" + IDS_2090 "Video işleyici başlatılamadı." + IDS_2091 "Varsayılan" + IDS_2092 "%i Bekleme durumları" + IDS_2093 "Tür" + IDS_2094 "PCap ayarlanamadı" + IDS_2095 "Herhangi bir PCap cihazı bulunamadı" + IDS_2096 "Geçersiz PCap cihazı" + IDS_2097 "Standart 2-button oyun kolları" + IDS_2098 "Standart 4-button oyun kolu" + IDS_2099 "Standart 6-button oyun kolu" + IDS_2100 "Standart 8-button oyun kolu" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Kontrol Sistemi" + IDS_2104 "Hiçbiri" + IDS_2105 "Klavye ivdirgeçleri yüklenemedi." + IDS_2106 "Ham girdi kaydedilemedi." + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "Disket %i (%s): %ls" + IDS_2110 "Tüm imajlar (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Gelişmiş sektör imajları (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basit sektör imajları (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Yüzey imajları (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" + IDS_2111 "FreeType başlatılamadı" + IDS_2112 "SDL başlatılamadı, SDL2.dll gerekmektedir" + IDS_2113 "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" + IDS_2114 "86Box'tan çıkmak istediğinize emin misiniz?" + IDS_2115 "Ghostscript başlatılamadı" + IDS_2116 "MO %i (%ls): %ls" + IDS_2117 "MO imajları (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" + IDS_2118 "86Box'a hoşgeldiniz!" + IDS_2119 "Dahili kontrolcü" + IDS_2120 "Çıkış" + IDS_2121 "Hiçbir ROM imajı bulunamadı" + IDS_2122 "Ayarları kaydetmek istediğinizden emin misiniz?" + IDS_2123 "Bu makineyi yeniden başlatacak." + IDS_2124 "Kaydet" + IDS_2125 "86Box Hakkında" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "Bir eski bilgisayar emülatörü\n\nYapanlar: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." - IDS_2127 "Tamam" - IDS_2128 "Donanım mevcut değil" + IDS_2127 "Bir eski bilgisayar emülatörü\n\nYapanlar: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." + IDS_2128 "Tamam" + IDS_2129 "Donanım mevcut değil" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "" LIB_NAME_PCAP " kurulu olduğundan ve " LIB_NAME_PCAP "-uyumlu bir internet ağında bulunduğunuzdan emin olun." - IDS_2130 "Geçersiz konfigürasyon" + IDS_2130 "" LIB_NAME_PCAP " kurulu olduğundan ve " LIB_NAME_PCAP "-uyumlu bir internet ağında bulunduğunuzdan emin olun." + IDS_2131 "Geçersiz konfigürasyon" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 LIB_NAME_FREETYPE " ESC/P yazıcı emülasyonu için gereklidir." + IDS_2132 LIB_NAME_FREETYPE " ESC/P yazıcı emülasyonu için gereklidir." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." + IDS_2133 LIB_NAME_GS " PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 LIB_NAME_FLUIDSYNTH " FluidSynth MIDI çıkışı için gereklidir." - IDS_2134 "Tam ekran moduna geçiliyor" - IDS_2135 "Bu mesajı bir daha gösterme" - IDS_2136 "Çıkış yapma" - IDS_2137 "Yeniden başlat" - IDS_2138 "Yeniden başlatma" - IDS_2139 "MO imajları (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2140 "CD-ROM imajları (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2141 "%hs Cihaz Konfigürasyonu" - IDS_2142 "Monitör uyku modunda" - IDS_2143 "OpenGL Gölgelendiricileri (*.GLSL)\0*.GLSL\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2144 "OpenGL ayarları" - IDS_2145 "Desteklenmeyen bir konfigürasyon yüklüyorsunuz" - IDS_2146 "Seçtiğiniz makineye uygun CPU (işlemci) türü filtrelemesi bu emülasyon için devre dışı bırakıldı.\n\nBu, normalde seçilen makine ile uyumlu olmayan bir CPU seçmenizi mümkün kılmaktadır. Ancak, bundan dolayı seçilen makinenin BIOS'u veya diğer yazılımlar ile uyumsuzluk sorunu yaşayabilirsiniz.\n\nBu filtrelemeyi devre dışı bırakmak emülatör tarafından resmi olarak desteklenmemektedir ve açtığınız bug (hata) raporları geçersiz olarak kapatılabilir." - IDS_2147 "Devam et" - IDS_2148 "Kaset: %s" - IDS_2149 "Kaset imajları (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2150 "Kartuş %i: %ls" - IDS_2151 "Kartuş imajları (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2152 "Oluşturucu başlatılırken hata oluştu" - IDS_2153 "OpenGL (3.0 Core) görüntüleyici başlatılamadı. Başka bir görüntüleyici kullanın." - IDS_2154 "Yürütmeye devam et" - IDS_2155 "Yürütmeyi duraklat" - IDS_2156 "Ctrl+Alt+Del" - IDS_2157 "Ctrl+Alt+Esc" - IDS_2158 "Makineyi yeniden başlat" - IDS_2159 "ACPI kapatma" - IDS_2160 "Ayarlar" - IDS_2161 "Daha erken sürüş" + IDS_2134 LIB_NAME_FLUIDSYNTH " FluidSynth MIDI çıkışı için gereklidir." + IDS_2135 "Tam ekran moduna geçiliyor" + IDS_2136 "Bu mesajı bir daha gösterme" + IDS_2137 "Çıkış yapma" + IDS_2138 "Yeniden başlat" + IDS_2139 "Yeniden başlatma" + IDS_2140 "MO imajları (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tüm dosyalar (*.*)\0*.*\0" + IDS_2141 "CD-ROM imajları (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tüm dosyalar (*.*)\0*.*\0" + IDS_2142 "%hs Cihaz Konfigürasyonu" + IDS_2143 "Monitör uyku modunda" + IDS_2144 "OpenGL Gölgelendiricileri (*.GLSL)\0*.GLSL\0Tüm dosyalar (*.*)\0*.*\0" + IDS_2145 "OpenGL ayarları" + IDS_2146 "Desteklenmeyen bir konfigürasyon yüklüyorsunuz" + IDS_2147 "Seçtiğiniz makineye uygun CPU (işlemci) türü filtrelemesi bu emülasyon için devre dışı bırakıldı.\n\nBu, normalde seçilen makine ile uyumlu olmayan bir CPU seçmenizi mümkün kılmaktadır. Ancak, bundan dolayı seçilen makinenin BIOS'u veya diğer yazılımlar ile uyumsuzluk sorunu yaşayabilirsiniz.\n\nBu filtrelemeyi devre dışı bırakmak emülatör tarafından resmi olarak desteklenmemektedir ve açtığınız bug (hata) raporları geçersiz olarak kapatılabilir." + IDS_2148 "Devam et" + IDS_2149 "Kaset: %s" + IDS_2150 "Kaset imajları (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tüm dosyalar (*.*)\0*.*\0" + IDS_2151 "Kartuş %i: %ls" + IDS_2152 "Kartuş imajları (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tüm dosyalar (*.*)\0*.*\0" + IDS_2153 "Oluşturucu başlatılırken hata oluştu" + IDS_2154 "OpenGL (3.0 Core) görüntüleyici başlatılamadı. Başka bir görüntüleyici kullanın." + IDS_2155 "Yürütmeye devam et" + IDS_2156 "Yürütmeyi duraklat" + IDS_2157 "Ctrl+Alt+Del" + IDS_2158 "Ctrl+Alt+Esc" + IDS_2159 "Makineyi yeniden başlat" + IDS_2160 "ACPI kapatma" + IDS_2161 "Ayarlar" + IDS_2162 "Daha erken sürüş" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index 3b20ba1ee..9f7f92cbe 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "&Приховати рядок стану", IDM_VID_HIDE_STATUS_BAR MENUITEM "&Приховати панель інструментів", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Змінний розмір вікна", IDM_VID_RESIZE MENUITEM "&Запам'ятати розмір і становище", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -177,7 +178,7 @@ BEGIN MENUITEM "&Знову завантажити попередній образ", IDM_CDROM_RELOAD MENUITEM SEPARATOR MENUITEM "&Образ...", IDM_CDROM_IMAGE - MENUITEM "&Тека", IDM_CDROM_DIR + MENUITEM "&Тека...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "Динамічний рекомпілятор" #define STR_VIDEO "Відеокарта:" +#define STR_VIDEO_2 "Відеокарта 2:" #define STR_VOODOO "Прискорювач Voodoo" #define STR_IBM8514 "Прискорювач IBM 8514/a" #define STR_XGA "Прискорювач XGA" @@ -333,6 +335,7 @@ END #define STR_BUS "Шина:" #define STR_CHANNEL "Канал:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "&Вказати..." #define STR_SECTORS "Сектора:" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "МБ" - IDS_2087 "Перевіряти BPB" - IDS_2088 "КБ" - IDS_2089 "Не вдалося ініціалізувати рендер відео." - IDS_2090 "За замовчуванням" - IDS_2091 "%i WS" - IDS_2092 "Тип" - IDS_2093 "Не вдалося налаштувати PCap" - IDS_2094 "Пристрої PCap не знайдені" - IDS_2095 "Невірний пристрій PCap" - IDS_2096 "Стандартний 2-кнопковий джойстик" - IDS_2097 "Стандартний 4-кнопковий джойстик" - IDS_2098 "Стандартний 6-кнопковий джойстик" - IDS_2099 "Стандартний 8-кнопковий джойстик" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Система управління польотом Thrustmaster" - IDS_2103 "Ні" - IDS_2104 "Неможливо завантажити прискорювачі клавіатури." - IDS_2105 "Неможливо зарреєструвати необроблене (RAW) введення." - IDS_2106 "%u" - IDS_2107 "%u МБ (CHS: %i, %i, %i)" - IDS_2108 "Дисковод %i (%s): %ls" - IDS_2109 "Всі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Всі файли (*.*)\0*.*\0" - IDS_2110 "Неможливо ініціалізувати FreeType" - IDS_2111 "Неможливо ініціалізувати SDL, потрібно SDL2.dll" - IDS_2112 "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" - IDS_2113 "Ви впевнені, що хочете вийти з 86Box?" - IDS_2114 "Неможливо ініціалізувати Ghostscript" - IDS_2115 "Магнітооптичний %i (%ls): %ls" - IDS_2116 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" - IDS_2117 "Ласкаво просимо в 86Box!" - IDS_2118 "Вбудований контролер" - IDS_2119 "Вихід" - IDS_2120 "ПЗУ не знайдені" - IDS_2121 "Чи бажаєте ви зберегти налаштування?" - IDS_2122 "Це призведе до холодної перезагрузки емульованої машини." - IDS_2123 "Зберегти" - IDS_2124 "Про 86Box" - IDS_2125 "86Box v." EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "Перевіряти BPB" + IDS_2089 "КБ" + IDS_2090 "Не вдалося ініціалізувати рендер відео." + IDS_2091 "За замовчуванням" + IDS_2092 "%i WS" + IDS_2093 "Тип" + IDS_2094 "Не вдалося налаштувати PCap" + IDS_2095 "Пристрої PCap не знайдені" + IDS_2096 "Невірний пристрій PCap" + IDS_2097 "Стандартний 2-кнопковий джойстик" + IDS_2098 "Стандартний 4-кнопковий джойстик" + IDS_2099 "Стандартний 6-кнопковий джойстик" + IDS_2100 "Стандартний 8-кнопковий джойстик" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Система управління польотом Thrustmaster" + IDS_2104 "Ні" + IDS_2105 "Неможливо завантажити прискорювачі клавіатури." + IDS_2106 "Неможливо зарреєструвати необроблене (RAW) введення." + IDS_2107 "%u" + IDS_2108 "%u МБ (CHS: %i, %i, %i)" + IDS_2109 "Дисковод %i (%s): %ls" + IDS_2110 "Всі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Всі файли (*.*)\0*.*\0" + IDS_2111 "Неможливо ініціалізувати FreeType" + IDS_2112 "Неможливо ініціалізувати SDL, потрібно SDL2.dll" + IDS_2113 "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" + IDS_2114 "Ви впевнені, що хочете вийти з 86Box?" + IDS_2115 "Неможливо ініціалізувати Ghostscript" + IDS_2116 "Магнітооптичний %i (%ls): %ls" + IDS_2117 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" + IDS_2118 "Ласкаво просимо в 86Box!" + IDS_2119 "Вбудований контролер" + IDS_2120 "Вихід" + IDS_2121 "ПЗУ не знайдені" + IDS_2122 "Чи бажаєте ви зберегти налаштування?" + IDS_2123 "Це призведе до холодної перезагрузки емульованої машини." + IDS_2124 "Зберегти" + IDS_2125 "Про 86Box" + IDS_2126 "86Box v." EMU_VERSION - IDS_2126 "Емулятор старих комп'ютерів\n\nАвтори: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." - IDS_2127 "OK" - IDS_2128 "Обладнання недоступне" + IDS_2127 "Емулятор старих комп'ютерів\n\nАвтори: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." + IDS_2128 "OK" + IDS_2129 "Обладнання недоступне" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Переконайтесь, що " LIB_NAME_PCAP " встановлений і ваше мережеве з'єднання, сумісне з " LIB_NAME_PCAP "." - IDS_2130 "Неприпустима конфігурація" + IDS_2130 "Переконайтесь, що " LIB_NAME_PCAP " встановлений і ваше мережеве з'єднання, сумісне з " LIB_NAME_PCAP "." + IDS_2131 "Неприпустима конфігурація" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 "Для емуляції принтера ESC/P потрібно " LIB_NAME_FREETYPE "." + IDS_2132 "Для емуляції принтера ESC/P потрібно " LIB_NAME_FREETYPE "." #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." + IDS_2133 LIB_NAME_GS " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 "Для FluidSynth MIDI-висновку потрібно " LIB_NAME_FLUIDSYNTH "." - IDS_2134 "Вхід у повноекранний режим" - IDS_2135 "Більше не показувати це повідомлення" - IDS_2136 "Не виходити" - IDS_2137 "Перезавантажити" - IDS_2138 "Не перезавантажувати" - IDS_2139 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Усі файли (*.*)\0*.*\0" - IDS_2140 "Образи CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Усі файли (*.*)\0*.*\0" - IDS_2141 "Конфігурація пристрою %hs" - IDS_2142 "Монітор у сплячому режимі" - IDS_2143 "Шейдери OpenGL (*.GLSL)\0*.GLSL\0Усі файли (*.*)\0*.*\0" - IDS_2144 "Параметри OpenGL" - IDS_2145 "Ви завантажуєте непідтримувану конфігурацію" - IDS_2146 "Вибір типів ЦП для цієї системної плати на даній емульованій машині відключено.\n\nЦе дозволяє вибрати процесор, який в іншому випадку не сумісний з вибраною материнською платою. Однак, ви можете зіткнутися з несумісністю з BIOS материнської плати або іншим ПО.\n\nВключення цього параметра офіційно не підтримується, і всі подані звіти про помилки можуть бути закриті як недійсні." - IDS_2147 "Продовжити" - IDS_2148 "Касета: %s" - IDS_2149 "Образи касет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Усі файли (*.*)\0*. *\0" - IDS_2150 "Картридж %i: %ls" - IDS_2151 "Образи картриджів (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Всі файли (*.*)\0*.*\0" - IDS_2152 "Помилка ініціалізації рендерера" - IDS_2153 "Неможливо ініціалізувати рендерер OpenGL (3.0). Будь ласка, використовуйте інший рендерер." - IDS_2154 "Відновити виконання" - IDS_2155 "Призупинити виконання" - IDS_2156 "Натиснути Ctrl+Alt+Del" - IDS_2157 "Натиснути Ctrl+Alt+Esc" - IDS_2158 "Холодне перезавантаження" - IDS_2159 "Сигнал завершення ACPI" - IDS_2160 "Налаштування машини" - IDS_2161 "Більш ранній дисковод" + IDS_2134 "Для FluidSynth MIDI-висновку потрібно " LIB_NAME_FLUIDSYNTH "." + IDS_2135 "Вхід у повноекранний режим" + IDS_2136 "Більше не показувати це повідомлення" + IDS_2137 "Не виходити" + IDS_2138 "Перезавантажити" + IDS_2139 "Не перезавантажувати" + IDS_2140 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Усі файли (*.*)\0*.*\0" + IDS_2141 "Образи CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Усі файли (*.*)\0*.*\0" + IDS_2142 "Конфігурація пристрою %hs" + IDS_2143 "Монітор у сплячому режимі" + IDS_2144 "Шейдери OpenGL (*.GLSL)\0*.GLSL\0Усі файли (*.*)\0*.*\0" + IDS_2145 "Параметри OpenGL" + IDS_2146 "Ви завантажуєте непідтримувану конфігурацію" + IDS_2147 "Вибір типів ЦП для цієї системної плати на даній емульованій машині відключено.\n\nЦе дозволяє вибрати процесор, який в іншому випадку не сумісний з вибраною материнською платою. Однак, ви можете зіткнутися з несумісністю з BIOS материнської плати або іншим ПО.\n\nВключення цього параметра офіційно не підтримується, і всі подані звіти про помилки можуть бути закриті як недійсні." + IDS_2148 "Продовжити" + IDS_2149 "Касета: %s" + IDS_2150 "Образи касет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Усі файли (*.*)\0*. *\0" + IDS_2151 "Картридж %i: %ls" + IDS_2152 "Образи картриджів (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Всі файли (*.*)\0*.*\0" + IDS_2153 "Помилка ініціалізації рендерера" + IDS_2154 "Неможливо ініціалізувати рендерер OpenGL (3.0). Будь ласка, використовуйте інший рендерер." + IDS_2155 "Відновити виконання" + IDS_2156 "Призупинити виконання" + IDS_2157 "Натиснути Ctrl+Alt+Del" + IDS_2158 "Натиснути Ctrl+Alt+Esc" + IDS_2159 "Холодне перезавантаження" + IDS_2160 "Сигнал завершення ACPI" + IDS_2161 "Налаштування машини" + IDS_2162 "Більш ранній дисковод" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index 6a1a2a55a..88a7e9055 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -34,6 +34,7 @@ BEGIN MENUITEM "隐藏状态栏(&H)", IDM_VID_HIDE_STATUS_BAR MENUITEM "隐藏工具栏(&T)", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR + MENUITEM "Show non-primary monitors(&S)", IDM_VID_MONITORS MENUITEM "窗口大小可调(&R)", IDM_VID_RESIZE MENUITEM "记住窗口大小和位置(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -176,8 +177,8 @@ BEGIN MENUITEM "空置驱动器(&M)", IDM_CDROM_EMPTY MENUITEM "载入上一个镜像(&R)", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "镜像(&I)", IDM_CDROM_IMAGE - MENUITEM "文件夹(&F)", IDM_CDROM_DIR + MENUITEM "镜像(&I)...", IDM_CDROM_IMAGE + MENUITEM "文件夹(&F)...", IDM_CDROM_DIR END END @@ -271,6 +272,7 @@ END #define STR_DYNAREC "动态重编译器" #define STR_VIDEO "显卡:" +#define STR_VIDEO_2 "显卡 2:" #define STR_VOODOO "Voodoo Graphics" #define STR_IBM8514 "IBM 8514/a Graphics" #define STR_XGA "XGA Graphics" @@ -333,6 +335,7 @@ END #define STR_BUS "总线:" #define STR_CHANNEL "通道:" #define STR_ID "ID:" +#define STR_SPEED "Speed:" #define STR_SPECIFY "指定(&S)..." #define STR_SECTORS "扇区(S):" @@ -422,102 +425,103 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "检查 BPB" - IDS_2088 "KB" - IDS_2089 "无法初始化视频渲染器。" - IDS_2090 "默认" - IDS_2091 "%i 等待状态 (WS)" - IDS_2092 "类型" - IDS_2093 "设置 PCap 失败" - IDS_2094 "未找到 PCap 设备" - IDS_2095 "无效 PCap 设备" - IDS_2096 "标准 2 键操纵杆" - IDS_2097 "标准 4 键操纵杆" - IDS_2098 "标准 6 键操纵杆" - IDS_2099 "标准 8 键操纵杆" - IDS_2100 "CH Flightstick Pro" - IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" - IDS_2103 "无" - IDS_2104 "无法加载键盘加速器。" - IDS_2105 "无法注册原始输入。" - IDS_2106 "%u" - IDS_2107 "%u MB (CHS: %i, %i, %i)" - IDS_2108 "软盘 %i (%s): %ls" - IDS_2109 "所有镜像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区镜像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区镜像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 镜像 (*.FDI)\0*.FDI\0表面镜像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" - IDS_2110 "无法初始化 FreeType" - IDS_2111 "无法初始化 SDL,需要 SDL2.dll" - IDS_2112 "确定要硬重置模拟器吗?" - IDS_2113 "确定要退出 86Box 吗?" - IDS_2114 "无法初始化 Ghostscript" - IDS_2115 "磁光盘 %i (%ls): %ls" - IDS_2116 "磁光盘镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" - IDS_2117 "欢迎使用 86Box!" - IDS_2118 "内部控制器" - IDS_2119 "退出" - IDS_2120 "找不到 ROM" - IDS_2121 "要保存设置吗?" - IDS_2122 "此操作将硬重置模拟器。" - IDS_2123 "保存" - IDS_2124 "关于 86Box" - IDS_2125 "86Box v" EMU_VERSION + IDS_2087 "Speed" + IDS_2088 "检查 BPB" + IDS_2089 "KB" + IDS_2090 "无法初始化视频渲染器。" + IDS_2091 "默认" + IDS_2092 "%i 等待状态 (WS)" + IDS_2093 "类型" + IDS_2094 "设置 PCap 失败" + IDS_2095 "未找到 PCap 设备" + IDS_2096 "无效 PCap 设备" + IDS_2097 "标准 2 键操纵杆" + IDS_2098 "标准 4 键操纵杆" + IDS_2099 "标准 6 键操纵杆" + IDS_2100 "标准 8 键操纵杆" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "无" + IDS_2105 "无法加载键盘加速器。" + IDS_2106 "无法注册原始输入。" + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "软盘 %i (%s): %ls" + IDS_2110 "所有镜像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区镜像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区镜像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 镜像 (*.FDI)\0*.FDI\0表面镜像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" + IDS_2111 "无法初始化 FreeType" + IDS_2112 "无法初始化 SDL,需要 SDL2.dll" + IDS_2113 "确定要硬重置模拟器吗?" + IDS_2114 "确定要退出 86Box 吗?" + IDS_2115 "无法初始化 Ghostscript" + IDS_2116 "磁光盘 %i (%ls): %ls" + IDS_2117 "磁光盘镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" + IDS_2118 "欢迎使用 86Box!" + IDS_2119 "内部控制器" + IDS_2120 "退出" + IDS_2121 "找不到 ROM" + IDS_2122 "要保存设置吗?" + IDS_2123 "此操作将硬重置模拟器。" + IDS_2124 "保存" + IDS_2125 "关于 86Box" + IDS_2126 "86Box v" EMU_VERSION - IDS_2126 "一个旧式计算机模拟器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" - IDS_2127 "确定" - IDS_2128 "硬件不可用" + IDS_2127 "一个旧式计算机模拟器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" + IDS_2128 "确定" + IDS_2129 "硬件不可用" #ifdef _WIN32 #define LIB_NAME_PCAP "WinPcap" #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "请确认 " LIB_NAME_PCAP " 已安装且使用兼容 " LIB_NAME_PCAP " 的网络连接。" - IDS_2130 "无效配置" + IDS_2130 "请确认 " LIB_NAME_PCAP " 已安装且使用兼容 " LIB_NAME_PCAP " 的网络连接。" + IDS_2131 "无效配置" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 "ESC/P 打印机模拟需要" LIB_NAME_FREETYPE + IDS_2132 "ESC/P 打印机模拟需要" LIB_NAME_FREETYPE #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" + IDS_2133 LIB_NAME_GS " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif - IDS_2133 "FluidSynth MIDI 输出需要" LIB_NAME_FLUIDSYNTH - IDS_2134 "正在进入全屏模式" - IDS_2135 "不要再显示此消息" - IDS_2136 "不退出" - IDS_2137 "重置" - IDS_2138 "不重置" - IDS_2139 "磁光盘镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" - IDS_2140 "光盘镜像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有文件 (*.*)\0*.*\0" - IDS_2141 "%hs 设备配置" - IDS_2142 "显示器处在睡眠状态" - IDS_2143 "OpenGL 着色器 (*.GLSL)\0*.GLSL\0所有文件 (*.*)\0*.*\0" - IDS_2144 "OpenGL 选项" - IDS_2145 "正在载入一个不受支持的配置" - IDS_2146 "此模拟计算机禁用了基于选定计算机的 CPU 类型过滤。\n\n能够选中与所选机器本不兼容的 CPU,但是可能会遇到与机器 BIOS 或其他软件不兼容的问题。\n\n启用此设置不受官方支持,并且提交的任何错误报告可能会视为无效而关闭。" - IDS_2147 "继续" - IDS_2148 "磁带: %s" - IDS_2149 "磁带镜像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有文件 (*.*)\0*.*\0" - IDS_2150 "卡带 %i: %ls" - IDS_2151 "卡带镜像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有文件 (*.*)\0*.*\0" - IDS_2152 "初始化渲染器时出错" - IDS_2153 "无法初始化 OpenGL (3.0 核心) 渲染器。请使用其他渲染器。" - IDS_2154 "恢复执行" - IDS_2155 "暂停执行" - IDS_2156 "按下 Ctrl+Alt+Del" - IDS_2157 "按下 Ctrl+Alt+Esc" - IDS_2158 "硬重置" - IDS_2159 "ACPI 关机" - IDS_2160 "设置" - IDS_2161 "早先的驱动器" + IDS_2134 "FluidSynth MIDI 输出需要" LIB_NAME_FLUIDSYNTH + IDS_2135 "正在进入全屏模式" + IDS_2136 "不要再显示此消息" + IDS_2137 "不退出" + IDS_2138 "重置" + IDS_2139 "不重置" + IDS_2140 "磁光盘镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" + IDS_2141 "光盘镜像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有文件 (*.*)\0*.*\0" + IDS_2142 "%hs 设备配置" + IDS_2143 "显示器处在睡眠状态" + IDS_2144 "OpenGL 着色器 (*.GLSL)\0*.GLSL\0所有文件 (*.*)\0*.*\0" + IDS_2145 "OpenGL 选项" + IDS_2146 "正在载入一个不受支持的配置" + IDS_2147 "此模拟计算机禁用了基于选定计算机的 CPU 类型过滤。\n\n能够选中与所选机器本不兼容的 CPU,但是可能会遇到与机器 BIOS 或其他软件不兼容的问题。\n\n启用此设置不受官方支持,并且提交的任何错误报告可能会视为无效而关闭。" + IDS_2148 "继续" + IDS_2149 "磁带: %s" + IDS_2150 "磁带镜像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有文件 (*.*)\0*.*\0" + IDS_2151 "卡带 %i: %ls" + IDS_2152 "卡带镜像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有文件 (*.*)\0*.*\0" + IDS_2153 "初始化渲染器时出错" + IDS_2154 "无法初始化 OpenGL (3.0 核心) 渲染器。请使用其他渲染器。" + IDS_2155 "恢复执行" + IDS_2156 "暂停执行" + IDS_2157 "按下 Ctrl+Alt+Del" + IDS_2158 "按下 Ctrl+Alt+Esc" + IDS_2159 "硬重置" + IDS_2160 "ACPI 关机" + IDS_2161 "设置" + IDS_2162 "早先的驱动器" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc new file mode 100644 index 000000000..e06f8525c --- /dev/null +++ b/src/win/languages/zh-TW.rc @@ -0,0 +1,629 @@ +//////////////////////////////////////////////////////////////////////////// +// Traditional Chinese resources + +#ifdef _WIN32 +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL +#pragma code_page(65001) +#endif //_WIN32 + +#define AUTHORS + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +MainMenu MENU DISCARDABLE +BEGIN + POPUP "動作(&A)" + BEGIN + MENUITEM "鍵盤需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "將右 CTRL 鍵映射為左 ALT 鍵(&R)", IDM_ACTION_RCTRL_IS_LALT + MENUITEM SEPARATOR + MENUITEM "硬重設(&H)...", IDM_ACTION_HRESET + MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM SEPARATOR + MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC + MENUITEM SEPARATOR + MENUITEM "暫停(&P)", IDM_ACTION_PAUSE + MENUITEM SEPARATOR + MENUITEM "退出(&X)...", IDM_ACTION_EXIT + END + POPUP "檢視(&V)" + BEGIN + MENUITEM "隱藏狀態列(&H)", IDM_VID_HIDE_STATUS_BAR + MENUITEM "隱藏工具列(&T)", IDM_VID_HIDE_TOOLBAR + MENUITEM SEPARATOR + MENUITEM "Show non-primary monitors(&S)", IDM_VID_MONITORS + MENUITEM "視窗大小可調(&R)", IDM_VID_RESIZE + MENUITEM "記住視窗大小和位置(&E)", IDM_VID_REMEMBER + MENUITEM SEPARATOR + POPUP "渲染器(&N)" + BEGIN + MENUITEM "SDL (軟體)(&S)", IDM_VID_SDL_SW + MENUITEM "SDL (硬體)(&H)", IDM_VID_SDL_HW + MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL + MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE +#ifdef USE_VNC + MENUITEM "VNC(&V)", IDM_VID_VNC +#endif + END + MENUITEM SEPARATOR + MENUITEM "指定視窗大小...", IDM_VID_SPECIFY_DIM + MENUITEM "強制 4:3 顯示比例(&O)", IDM_VID_FORCE43 + POPUP "視窗縮放係數(&W)" + BEGIN + MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X + MENUITEM "1x(&1)", IDM_VID_SCALE_2X + MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X + MENUITEM "2x(&2)", IDM_VID_SCALE_4X + END + POPUP "過濾方式" + BEGIN + MENUITEM "鄰近(&N)", IDM_VID_FILTER_NEAREST + MENUITEM "線性(&L)", IDM_VID_FILTER_LINEAR + END + MENUITEM "HiDPI 縮放(&D)", IDM_VID_HIDPI + MENUITEM SEPARATOR + MENUITEM "全螢幕(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + POPUP "全螢幕拉伸模式(&S)" + BEGIN + MENUITEM "全螢幕拉伸(&F)", IDM_VID_FS_FULL + MENUITEM "4:3(&4)", IDM_VID_FS_43 + MENUITEM "保持比例(&S)", IDM_VID_FS_KEEPRATIO + MENUITEM "整數比例(&I)", IDM_VID_FS_INT + END + POPUP "EGA/(S)VGA 設定(&G)" + BEGIN + MENUITEM "VGA 顯示器反色顯示(&I)", IDM_VID_INVERT + POPUP "VGA 螢幕類型(&T)" + BEGIN + MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB + MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO + MENUITEM "琥珀色單色顯示器(&A)", IDM_VID_GRAY_AMBER + MENUITEM "綠色單色顯示器(&G)", IDM_VID_GRAY_GREEN + MENUITEM "白色單色顯示器(&W)", IDM_VID_GRAY_WHITE + END + POPUP "灰度轉換類型(&C)" + BEGIN + MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 + MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 + MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE + END + END + MENUITEM SEPARATOR + MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 過掃描(&G)", IDM_VID_OVERSCAN + MENUITEM "變更單色顯示對比度(&M)", IDM_VID_CGACON + END + MENUITEM "介質(&M)", IDM_MEDIA + POPUP "工具(&T)" + BEGIN + MENUITEM "設定(&S)...", IDM_CONFIG + MENUITEM "更新狀態列圖示(&U)", IDM_UPDATE_ICONS + MENUITEM SEPARATOR + MENUITEM "擷圖(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM SEPARATOR + MENUITEM "首選項(&P)...", IDM_PREFERENCES + MENUITEM "啟用 Discord 整合(&D)", IDM_DISCORD + MENUITEM SEPARATOR + MENUITEM "音量增益(&G)...", IDM_SND_GAIN +#ifdef MTR_ENABLED + MENUITEM SEPARATOR + MENUITEM "開始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "結束追踪\tCtrl+T", IDM_ACTION_END_TRACE +#endif + END + POPUP "說明(&H)" + BEGIN + MENUITEM "文件(&D)...", IDM_DOCS + MENUITEM "關於 86Box(&A)...", IDM_ABOUT + END +END + +StatusBarMenu MENU DISCARDABLE +BEGIN + MENUITEM SEPARATOR +END + +CassetteSubmenu MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "新增鏡像(&N)...", IDM_CASSETTE_IMAGE_NEW + MENUITEM SEPARATOR + MENUITEM "開啟已存在的鏡像(&E)...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "開啟已存在的鏡像並寫保護(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM SEPARATOR + MENUITEM "錄製(&R)", IDM_CASSETTE_RECORD + MENUITEM "播放(&P)", IDM_CASSETTE_PLAY + MENUITEM "倒帶至起點(&R)", IDM_CASSETTE_REWIND + MENUITEM "快進至終點(&F)", IDM_CASSETTE_FAST_FORWARD + MENUITEM SEPARATOR + MENUITEM "彈出(&J)", IDM_CASSETTE_EJECT + END +END + +CartridgeSubmenu MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "鏡像(&I)...", IDM_CARTRIDGE_IMAGE + MENUITEM SEPARATOR + MENUITEM "彈出(&J)", IDM_CARTRIDGE_EJECT + END +END + +FloppySubmenu MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "新增鏡像(&N)...", IDM_FLOPPY_IMAGE_NEW + MENUITEM SEPARATOR + MENUITEM "開啟已存在的鏡像(&E)...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "開啟已存在的鏡像並寫保護(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM SEPARATOR + MENUITEM "匯出為 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM SEPARATOR + MENUITEM "彈出(&J)", IDM_FLOPPY_EJECT + END +END + +CdromSubmenu MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "靜音(&M)", IDM_CDROM_MUTE + MENUITEM SEPARATOR + MENUITEM "空置光碟機(&M)", IDM_CDROM_EMPTY + MENUITEM "載入上一個鏡像(&R)", IDM_CDROM_RELOAD + MENUITEM SEPARATOR + MENUITEM "鏡像(&I)...", IDM_CDROM_IMAGE + MENUITEM "資料夾(&F)...", IDM_CDROM_DIR + END +END + +ZIPSubmenu MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "新增鏡像(&N)...", IDM_ZIP_IMAGE_NEW + MENUITEM SEPARATOR + MENUITEM "開啟已存在的鏡像(&E)...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "開啟已存在的鏡像並寫保護(&W)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM SEPARATOR + MENUITEM "彈出(&J)", IDM_ZIP_EJECT + MENUITEM "載入上一個鏡像(&R)", IDM_ZIP_RELOAD + END +END + +MOSubmenu MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "新增鏡像(&N)...", IDM_MO_IMAGE_NEW + MENUITEM SEPARATOR + MENUITEM "開啟已存在的鏡像(&E)...", IDM_MO_IMAGE_EXISTING + MENUITEM "開啟已存在的鏡像並寫保護(&W)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM SEPARATOR + MENUITEM "鏡像(&J)", IDM_MO_EJECT + MENUITEM "載入上一個鏡像(&R)", IDM_MO_RELOAD + END +END + +VidGLSubMenu MENU DISCARDABLE +BEGIN + POPUP "目標幀率(&F)" + BEGIN + MENUITEM "與視訊同步(&S)", IDM_VID_GL_FPS_BLITTER + MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 + MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 + MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 + MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 + MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 + END + MENUITEM "垂直同步(&V)", IDM_VID_GL_VSYNC + MENUITEM "選擇著色器(&S)...", IDM_VID_GL_SHADER + MENUITEM "移除著色器(&R)", IDM_VID_GL_NOSHADER +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +#define STR_PREFERENCES "首選項" +#define STR_SND_GAIN "音量增益" +#define STR_NEW_FLOPPY "新增鏡像" +#define STR_CONFIG "設定" +#define STR_SPECIFY_DIM "指定主視窗大小" + +#define STR_OK "確定" +#define STR_CANCEL "取消" +#define STR_GLOBAL "將以上設定存儲為全局預設值(&G)" +#define STR_DEFAULT "預設(&D)" +#define STR_LANGUAGE "語言:" +#define STR_ICONSET "圖示集:" + +#define STR_GAIN "增益" + +#define STR_FILE_NAME "檔案名:" +#define STR_DISK_SIZE "磁碟大小:" +#define STR_RPM_MODE "轉速 (RPM) 模式:" +#define STR_PROGRESS "進度:" + +#define STR_WIDTH "寬度:" +#define STR_HEIGHT "高度:" +#define STR_LOCK_TO_SIZE "鎖定此大小" + +#define STR_MACHINE_TYPE "機器類型:" +#define STR_MACHINE "機型:" +#define STR_CONFIGURE "配置" +#define STR_CPU_TYPE "CPU 類型:" +#define STR_CPU_SPEED "速度:" +#define STR_FPU "浮點處理器 (FPU):" +#define STR_WAIT_STATES "等待狀態 (WS):" +#define STR_MB "MB" +#define STR_MEMORY "記憶體:" +#define STR_TIME_SYNC "時間同步" +#define STR_DISABLED "禁用" +#define STR_ENABLED_LOCAL "啟用 (本地時間)" +#define STR_ENABLED_UTC "啟用 (UTC)" +#define STR_DYNAREC "動態重編譯器" + +#define STR_VIDEO "顯示卡:" +#define STR_VIDEO_2 "顯示卡 2:" +#define STR_VOODOO "Voodoo Graphics" +#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" + +#define STR_MOUSE "滑鼠:" +#define STR_JOYSTICK "搖桿:" +#define STR_JOY1 "搖桿 1..." +#define STR_JOY2 "搖桿 2..." +#define STR_JOY3 "搖桿 3..." +#define STR_JOY4 "搖桿 4..." + +#define STR_SOUND "音訊卡:" +#define STR_MIDI_OUT "MIDI 輸出裝置:" +#define STR_MIDI_IN "MIDI 輸入裝置:" +#define STR_MPU401 "獨立 MPU-401" +#define STR_SSI "Innovation SSI-2001" +#define STR_CMS "CMS / Game Blaster" +#define STR_GUS "Gravis Ultrasound" +#define STR_FLOAT "使用單精度浮點 (FLOAT32)" +#define STR_FM_DRIVER "調頻合成器驅動器" +#define STR_FM_DRV_NUKED "Nuked (更準確)" +#define STR_FM_DRV_YMFM "YMFM (更快)" + +#define STR_NET_TYPE "網路類型:" +#define STR_PCAP "PCap 裝置:" +#define STR_NET "網路配接器:" + +#define STR_COM1 "COM1 裝置:" +#define STR_COM2 "COM2 裝置:" +#define STR_COM3 "COM3 裝置:" +#define STR_COM4 "COM4 裝置:" +#define STR_LPT1 "LPT1 裝置:" +#define STR_LPT2 "LPT2 裝置:" +#define STR_LPT3 "LPT3 裝置:" +#define STR_LPT4 "LPT4 裝置:" +#define STR_SERIAL1 "序列埠 1" +#define STR_SERIAL2 "序列埠 2" +#define STR_SERIAL3 "序列埠 3" +#define STR_SERIAL4 "序列埠 4" +#define STR_PARALLEL1 "並列埠 1" +#define STR_PARALLEL2 "並列埠 2" +#define STR_PARALLEL3 "並列埠 3" +#define STR_PARALLEL4 "並列埠 4" + +#define STR_HDC "硬碟控制器:" +#define STR_FDC "軟碟控制器:" +#define STR_IDE_TER "第三 IDE 控制器" +#define STR_IDE_QUA "第四 IDE 控制器" +#define STR_SCSI "SCSI" +#define STR_SCSI_1 "控制器 1:" +#define STR_SCSI_2 "控制器 2:" +#define STR_SCSI_3 "控制器 3:" +#define STR_SCSI_4 "控制器 4:" +#define STR_CASSETTE "磁帶" + +#define STR_HDD "硬碟:" +#define STR_NEW "新增(&N)..." +#define STR_EXISTING "已有鏡像(&E)..." +#define STR_REMOVE "移除(&R)" +#define STR_BUS "匯流排:" +#define STR_CHANNEL "通道:" +#define STR_ID "ID:" +#define STR_SPEED "Speed:" + +#define STR_SPECIFY "指定(&S)..." +#define STR_SECTORS "磁區(S):" +#define STR_HEADS "磁頭(H):" +#define STR_CYLS "柱面(C):" +#define STR_SIZE_MB "大小 (MB):" +#define STR_TYPE "類型:" +#define STR_IMG_FORMAT "鏡像格式:" +#define STR_BLOCK_SIZE "塊大小:" + +#define STR_FLOPPY_DRIVES "軟碟機:" +#define STR_TURBO "加速時序" +#define STR_CHECKBPB "檢查 BPB" +#define STR_CDROM_DRIVES "光碟機:" +#define STR_CD_SPEED "速度:" +#define STR_EARLY "早先的光碟機" + +#define STR_MO_DRIVES "磁光碟機:" +#define STR_ZIP_DRIVES "ZIP 磁碟機:" +#define STR_250 "ZIP 250" + +#define STR_ISARTC "ISA 實時時鐘:" +#define STR_ISAMEM "ISA 記憶體擴充" +#define STR_ISAMEM_1 "擴充卡 1:" +#define STR_ISAMEM_2 "擴充卡 2:" +#define STR_ISAMEM_3 "擴充卡 3:" +#define STR_ISAMEM_4 "擴充卡 4:" +#define STR_BUGGER "ISABugger 裝置" +#define STR_POSTCARD "自檢 (POST) 卡" + +#define FONT_SIZE 9 +#define FONT_NAME "Microsoft JhengHei" + +#include "dialogs.rc" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + 2048 "86Box" + IDS_2049 "錯誤" + IDS_2050 "致命錯誤" + IDS_2051 " - 已暫停" + IDS_2052 "按下 Ctrl+Alt+PgDn 返回到視窗模式。" + IDS_2053 "速度" + IDS_2054 "ZIP %03i %i (%s): %ls" + IDS_2055 "ZIP 鏡像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" + IDS_2056 "86Box 找不到任何可用的 ROM 鏡像。\n\n請下載ROM 包並將其解壓到 ""roms"" 資料夾。" + IDS_2057 "(空)" + IDS_2058 "ZIP 鏡像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0所有檔案 (*.*)\0*.*\0" + IDS_2059 "加速" + IDS_2060 "開" + IDS_2061 "關" + IDS_2062 "所有鏡像 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本磁區鏡像 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面鏡像 (*.86F)\0*.86F\0" + IDS_2063 "由於 roms/machines 資料夾中缺少合適的 ROM,機型 ""%hs"" 不可用。將切換到其他可用機型。" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_2064 "由於 roms/video 資料夾中缺少合適的 ROM,顯示卡 ""%hs"" 不可用。將切換到其他可用顯示卡。" + IDS_2065 "機型" + IDS_2066 "顯示" + IDS_2067 "輸入裝置" + IDS_2068 "聲音" + IDS_2069 "網路" + IDS_2070 "連接埠 (COM 和 LPT)" + IDS_2071 "存儲控制器" + IDS_2072 "硬碟" + IDS_2073 "軟碟/光碟機" + IDS_2074 "其他可移除裝置" + IDS_2075 "其他周邊裝置" + IDS_2076 "表面鏡像 (*.86F)\0*.86F\0" + IDS_2077 "點擊視窗捕捉滑鼠" + IDS_2078 "按下 F8+F12 釋放滑鼠" + IDS_2079 "按下 F8+F12 或滑鼠中鍵釋放滑鼠" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_2080 "無法初始化 FluidSynth" + IDS_2081 "匯流排" + IDS_2082 "檔案" + IDS_2083 "C" + IDS_2084 "H" + IDS_2085 "S" + IDS_2086 "MB" + IDS_2087 "Speed" + IDS_2088 "檢查 BPB" + IDS_2089 "KB" + IDS_2090 "無法初始化視訊渲染器。" + IDS_2091 "預設" + IDS_2092 "%i 等待狀態 (WS)" + IDS_2093 "類型" + IDS_2094 "設定 PCap 失敗" + IDS_2095 "未找到 PCap 裝置" + IDS_2096 "無效 PCap 裝置" + IDS_2097 "標準 2 鍵搖桿" + IDS_2098 "標準 4 鍵搖桿" + IDS_2099 "標準 6 鍵搖桿" + IDS_2100 "標準 8 鍵搖桿" + IDS_2101 "CH Flightstick Pro" + IDS_2102 "Microsoft SideWinder Pad" + IDS_2103 "Thrustmaster Flight Control System" + IDS_2104 "無" + IDS_2105 "無法載入鍵盤加速器。" + IDS_2106 "無法註冊原始輸入。" + IDS_2107 "%u" + IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2109 "軟碟 %i (%s): %ls" + IDS_2110 "所有鏡像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0進階磁區鏡像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本磁區鏡像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 鏡像 (*.FDI)\0*.FDI\0表面鏡像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有檔案 (*.*)\0*.*\0" + IDS_2111 "無法初始化 FreeType" + IDS_2112 "無法初始化 SDL,需要 SDL2.dll" + IDS_2113 "確定要硬重設模擬器嗎?" + IDS_2114 "確定要退出 86Box 嗎?" + IDS_2115 "無法初始化 Ghostscript" + IDS_2116 "磁光碟 %i (%ls): %ls" + IDS_2117 "磁光碟鏡像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有檔案 (*.*)\0*.*\0" + IDS_2118 "歡迎使用 86Box!" + IDS_2119 "內部控制器" + IDS_2120 "退出" + IDS_2121 "找不到 ROM" + IDS_2122 "要保存設定嗎?" + IDS_2123 "此操作將硬重設模擬器。" + IDS_2124 "保存" + IDS_2125 "關於 86Box" + IDS_2126 "86Box v" EMU_VERSION + + IDS_2127 "一個舊式電腦模擬器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" + IDS_2128 "確定" + IDS_2129 "硬體不可用" +#ifdef _WIN32 +#define LIB_NAME_PCAP "WinPcap" +#else +#define LIB_NAME_PCAP "libpcap" +#endif + IDS_2130 "請確認 " LIB_NAME_PCAP " 已安裝且使用相容 " LIB_NAME_PCAP " 的網路連線。" + IDS_2131 "無效配置" +#ifdef _WIN32 +#define LIB_NAME_FREETYPE "freetype.dll" +#else +#define LIB_NAME_FREETYPE "libfreetype" +#endif + IDS_2132 "ESC/P 印表機模擬需要" LIB_NAME_FREETYPE +#ifdef _WIN32 +#define LIB_NAME_GS "gsdll32.dll" +#else +#define LIB_NAME_GS "libgs" +#endif + IDS_2133 LIB_NAME_GS " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被保存為 PostScript (.ps) 檔案。" +#ifdef _WIN32 +#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" +#else +#define LIB_NAME_FLUIDSYNTH "libfluidsynth" +#endif + IDS_2134 "FluidSynth MIDI 輸出需要" LIB_NAME_FLUIDSYNTH + IDS_2135 "正在進入全螢幕模式" + IDS_2136 "不要再顯示此消息" + IDS_2137 "不退出" + IDS_2138 "重設" + IDS_2139 "不重設" + IDS_2140 "磁光碟鏡像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有檔案 (*.*)\0*.*\0" + IDS_2141 "光碟鏡像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有檔案 (*.*)\0*.*\0" + IDS_2142 "%hs 裝置配置" + IDS_2143 "顯示器處在睡眠狀態" + IDS_2144 "OpenGL 著色器 (*.GLSL)\0*.GLSL\0所有檔案 (*.*)\0*.*\0" + IDS_2145 "OpenGL 選項" + IDS_2146 "正在載入一個不受支援的配置" + IDS_2147 "此模擬電腦禁用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" + IDS_2148 "繼續" + IDS_2149 "磁帶: %s" + IDS_2150 "磁帶鏡像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有檔案 (*.*)\0*.*\0" + IDS_2151 "卡帶 %i: %ls" + IDS_2152 "卡帶鏡像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有檔案 (*.*)\0*.*\0" + IDS_2153 "初始化渲染器時出錯" + IDS_2154 "無法初始化 OpenGL (3.0 核心) 渲染器。請使用其他渲染器。" + IDS_2155 "恢復執行" + IDS_2156 "暫停執行" + IDS_2157 "按下 Ctrl+Alt+Del" + IDS_2158 "按下 Ctrl+Alt+Esc" + IDS_2159 "硬重設" + IDS_2160 "ACPI 關機" + IDS_2161 "設定" + IDS_2162 "早先的光碟機" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_4096 "硬碟 (%s)" + IDS_4097 "%01i:%01i" + IDS_4098 "%01i" + IDS_4099 "不存在 MFM/RLL 或 ESDI CD-ROM 光碟機" + IDS_4100 "自訂..." + IDS_4101 "自訂 (大容量)..." + IDS_4102 "添加新硬碟" + IDS_4103 "添加已存在的硬碟" + IDS_4104 "HDI 磁碟鏡像不能超過 4 GB。" + IDS_4105 "磁碟鏡像不能超過 127 GB。" + IDS_4106 "硬碟鏡像 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0所有檔案 (*.*)\0*.*\0" + IDS_4107 "無法讀取檔案" + IDS_4108 "無法寫入檔案" + IDS_4109 "不支援非 512 位元組磁區大小的 HDI 或 HDX 鏡像。" + IDS_4110 "尚未支援 USB" + IDS_4111 "磁碟鏡像檔案已存在" + IDS_4112 "請指定有效的檔案名。" + IDS_4113 "已創建磁碟鏡像" + IDS_4114 "請確定此檔案已存在並可讀取。" + IDS_4115 "請確定此檔案保存在可寫目錄中。" + IDS_4116 "磁碟鏡像太大" + IDS_4117 "請記得為新創建的鏡像分區並格式化。" + IDS_4118 "選定的檔案將被覆蓋。確定繼續使用此檔案嗎?" + IDS_4119 "不支援的磁碟鏡像" + IDS_4120 "覆蓋" + IDS_4121 "不覆蓋" + IDS_4122 "原始鏡像 (.img)" + IDS_4123 "HDI 鏡像 (.hdi)" + IDS_4124 "HDX 鏡像 (.hdx)" + IDS_4125 "固定大小 VHD (.vhd)" + IDS_4126 "動態大小 VHD (.vhd)" + IDS_4127 "差分 VHD (.vhd)" + IDS_4128 "大塊 (2 MB)" + IDS_4129 "小塊 (512 KB)" + IDS_4130 "VHD 檔案 (*.VHD)\0*.VHD\0所有檔案 (*.*)\0*.*\0" + IDS_4131 "選擇父 VHD 檔案" + IDS_4132 "父映像可能在創建差異鏡像後被修改。\n\n如果鏡像檔案被移動或複製,或創建此磁碟的程式中存在錯誤,也可能發生這種情況。\n\n是否需要修復時間戳?" + IDS_4133 "父碟與子碟的時間戳不匹配" + IDS_4134 "無法修復 VHD 時間戳。" + IDS_4135 "%01i:%02i" + + IDS_4352 "MFM/RLL" + IDS_4353 "XTA" + IDS_4354 "ESDI" + IDS_4355 "IDE" + IDS_4356 "ATAPI" + IDS_4357 "SCSI" + + IDS_4608 "MFM/RLL (%01i:%01i)" + IDS_4609 "XTA (%01i:%01i)" + IDS_4610 "ESDI (%01i:%01i)" + IDS_4611 "IDE (%01i:%01i)" + IDS_4612 "ATAPI (%01i:%01i)" + IDS_4613 "SCSI (%01i:%02i)" + + IDS_5120 "光碟 %i (%s): %s" + + IDS_5376 "禁用" + IDS_5381 "ATAPI" + IDS_5382 "SCSI" + + IDS_5632 "禁用" + IDS_5637 "ATAPI (%01i:%01i)" + IDS_5638 "SCSI (%01i:%02i)" + + IDS_5888 "160 kB" + IDS_5889 "180 kB" + IDS_5890 "320 kB" + IDS_5891 "360 kB" + IDS_5892 "640 kB" + IDS_5893 "720 kB" + IDS_5894 "1.2 MB" + IDS_5895 "1.25 MB" + IDS_5896 "1.44 MB" + IDS_5897 "DMF (1024 簇)" + IDS_5898 "DMF (2048 簇)" + IDS_5899 "2.88 MB" + IDS_5900 "ZIP 100" + IDS_5901 "ZIP 250" + IDS_5902 "3.5 英寸 128 MB (ISO 10090)" + IDS_5903 "3.5 英寸 230 MB (ISO 13963)" + IDS_5904 "3.5 英寸 540 MB (ISO 15498)" + IDS_5905 "3.5 英寸 640 MB (ISO 15498)" + IDS_5906 "3.5 英寸 1.3 GB (GigaMO)" + IDS_5907 "3.5 英寸 2.3 GB (GigaMO 2)" + IDS_5908 "5.25 英寸 600 MB" + IDS_5909 "5.25 英寸 650 MB" + IDS_5910 "5.25 英寸 1 GB" + IDS_5911 "5.25 英寸 1.3 GB" + + IDS_6144 "標準轉速 (RPM)" + IDS_6145 "低於標準轉速的 1%" + IDS_6146 "低於標準轉速的 1.5%" + IDS_6147 "低於標準轉速的 2%" + + IDS_7168 "(系統預設)" +END +#define IDS_LANG_ENUS IDS_7168 + +// Traditional Chinese resources +///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/win.c b/src/win/win.c index e99b94984..3d46054a6 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Platform main support module for Windows. + * Platform main support module for Windows. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2021 Laci bá' + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2021 Laci bá' */ #define UNICODE #define NTDDI_VERSION 0x06010000 @@ -105,12 +105,13 @@ static const struct { void (*set_fs)(int fs); void (*reload)(void); } vid_apis[RENDERERS_NUM] = { - { "SDL_Software", 1, (int(*)(void*))sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "SDL_Hardware", 1, (int(*)(void*))sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "SDL_OpenGL", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload } - ,{ "OpenGL_Core", 1, (int(*)(void*))opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, opengl_reload} + { "SDL_Software", 1, (int (*)(void *)) sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, + { "SDL_Hardware", 1, (int (*)(void *)) sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, + { "SDL_OpenGL", 1, (int (*)(void *)) sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, + { "OpenGL_Core", 1, (int (*)(void *)) opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, opengl_reload } #ifdef USE_VNC - ,{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL, NULL } + , + { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL, NULL } #endif }; @@ -903,7 +904,7 @@ plat_get_global_config_dir(char* strptr) } void -plat_init_rom_paths() +plat_init_rom_paths(void) { wchar_t appdata_dir[1024] = { L'\0' }; @@ -1117,7 +1118,7 @@ plat_setfullscreen(int on) if (on && video_fullscreen_first) { video_fullscreen |= 2; - if (ui_msgbox_header(MBX_INFO | MBX_DONTASK, (wchar_t *) IDS_2134, (wchar_t *) IDS_2052) == 10) { + if (ui_msgbox_header(MBX_INFO | MBX_DONTASK, (wchar_t *) IDS_2135, (wchar_t *) IDS_2052) == 10) { video_fullscreen_first = 0; config_save(); } diff --git a/src/win/win_about.c b/src/win/win_about.c index 46009e686..c343eb7f0 100644 --- a/src/win/win_about.c +++ b/src/win/win_about.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handle the About dialog. + * Handle the About dialog. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017-2018 Fred N. van Kempen. */ #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -39,7 +39,7 @@ AboutDialogCreate(HWND hwnd) TASKDIALOGCONFIG tdconfig = { 0 }; TASKDIALOG_BUTTON tdbuttons[] = { {IDOK, EMU_SITE_W }, - { IDCANCEL, MAKEINTRESOURCE(IDS_2127)} + { IDCANCEL, MAKEINTRESOURCE(IDS_2128)} }; wchar_t emu_version[256]; @@ -52,10 +52,10 @@ AboutDialogCreate(HWND hwnd) tdconfig.hwndParent = hwnd; tdconfig.hInstance = hinstance; tdconfig.dwCommonButtons = 0; - tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_2124); + tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_2125); tdconfig.pszMainIcon = (PCWSTR) 10; tdconfig.pszMainInstruction = emu_version; - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2126); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2127); tdconfig.cButtons = ARRAYSIZE(tdbuttons); tdconfig.pButtons = tdbuttons; tdconfig.nDefaultButton = IDCANCEL; diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index dcff0d01b..00195bcda 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handle the platform-side of CDROM/ZIP/MO drives. + * Handle the platform-side of CDROM/ZIP/MO drives. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017-2018 Fred N. van Kempen. */ #define UNICODE #define BITMAP WINDOWS_BITMAP diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index 602aaa174..fee446310 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Windows device configuration dialog implementation. + * Windows device configuration dialog implementation. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -515,7 +515,7 @@ deviceconfig_inst_open(HWND hwnd, const device_t *device, int inst) *data++ = 0; /*no menu*/ *data++ = 0; /*predefined dialog box class*/ - data += wsprintf(data, plat_get_string(IDS_2141), device->name) + 1; + data += wsprintf(data, plat_get_string(IDS_2142), device->name) + 1; *data++ = 9; /*Point*/ data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 120); diff --git a/src/win/win_dialog.c b/src/win/win_dialog.c index fa48e067a..14f3119b6 100644 --- a/src/win/win_dialog.c +++ b/src/win/win_dialog.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Several dialogs for the application. + * Several dialogs for the application. * * * - * Author: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #define UNICODE #include @@ -60,7 +60,7 @@ ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, voi tdb_yes = { IDYES, STRING_OR_RESOURCE(btn1) }, tdb_no = { IDNO, STRING_OR_RESOURCE(btn2) }, tdb_cancel = { IDCANCEL, STRING_OR_RESOURCE(btn3) }, - tdb_exit = { IDCLOSE, MAKEINTRESOURCE(IDS_2119) }; + tdb_exit = { IDCLOSE, MAKEINTRESOURCE(IDS_2120) }; int ret = 0, checked = 0; /* Configure the default OK button. */ @@ -133,7 +133,7 @@ ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, voi tdconfig.pszMainInstruction = STRING_OR_RESOURCE(header); tdconfig.pButtons = tdbuttons; if (flags & MBX_DONTASK) - tdconfig.pszVerificationText = MAKEINTRESOURCE(IDS_2135); + tdconfig.pszVerificationText = MAKEINTRESOURCE(IDS_2136); /* Run the TaskDialog. */ TaskDialogIndirect(&tdconfig, &ret, NULL, &checked); diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index 98eb4739f..88fb632bc 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Try to load a support DLL. + * Try to load a support DLL. * * * - * Author: Fred N. van Kempen, + * Authors: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen + * Copyright 2017-2018 Fred N. van Kempen */ #include #include @@ -25,63 +25,59 @@ #include <86box/86box.h> #include <86box/plat_dynld.h> - #ifdef ENABLE_DYNLD_LOG int dynld_do_log = ENABLE_DYNLD_LOG; - static void dynld_log(const char *fmt, ...) { va_list ap; if (dynld_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define dynld_log(fmt, ...) +# define dynld_log(fmt, ...) #endif - void * dynld_module(const char *name, dllimp_t *table) { - HMODULE h; + HMODULE h; dllimp_t *imp; - void *func; + void *func; /* See if we can load the desired module. */ if ((h = LoadLibrary(name)) == NULL) { - dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); - return(NULL); + dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); + return (NULL); } /* Now load the desired function pointers. */ - for (imp=table; imp->name!=NULL; imp++) { - func = GetProcAddress(h, imp->name); - if (func == NULL) { - dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", - name, imp->name, GetLastError()); - FreeLibrary(h); - return(NULL); - } + for (imp = table; imp->name != NULL; imp++) { + func = GetProcAddress(h, imp->name); + if (func == NULL) { + dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", + name, imp->name, GetLastError()); + FreeLibrary(h); + return (NULL); + } - /* To overcome typing issues.. */ - *(char **)imp->func = (char *)func; + /* To overcome typing issues.. */ + *(char **) imp->func = (char *) func; } /* All good. */ dynld_log("loaded %s\n", name); - return((void *)h); + return ((void *) h); } - void dynld_close(void *handle) { if (handle != NULL) - FreeLibrary((HMODULE)handle); + FreeLibrary((HMODULE) handle); } diff --git a/src/win/win_icon.c b/src/win/win_icon.c index 7be30da1e..d23a325ff 100644 --- a/src/win/win_icon.c +++ b/src/win/win_icon.c @@ -1,17 +1,17 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implement the application's icon changing system. + * Implement the application's icon changing system. * * - * Authors: Laci bá' + * Authors: Laci bá' * - * Copyright 2021 Laci bá'. + * Copyright 2021 Laci bá'. */ #include @@ -32,7 +32,7 @@ HICON hIcon[256]; /* icon data loaded from resources */ char icon_set[256] = ""; /* name of the iconset to be used */ void -win_clear_icon_set() +win_clear_icon_set(void) { int i; @@ -44,7 +44,7 @@ win_clear_icon_set() } void -win_system_icon_set() +win_system_icon_set(void) { int i, x = win_get_system_metrics(SM_CXSMICON, dpi), y = win_get_system_metrics(SM_CYSMICON, dpi); @@ -125,7 +125,7 @@ win_get_icons_path(char *path_root) } void -win_load_icon_set() +win_load_icon_set(void) { win_clear_icon_set(); win_system_icon_set(); diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp index 30965efcd..ab9a2907e 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Joystick interface to host device. + * Joystick interface to host device. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #define DIRECTINPUT_VERSION 0x0800 #include diff --git a/src/win/win_joystick_rawinput.c b/src/win/win_joystick_rawinput.c index 51aa6c389..efaf76f01 100644 --- a/src/win/win_joystick_rawinput.c +++ b/src/win/win_joystick_rawinput.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * RawInput joystick interface. + * RawInput joystick interface. * - * Authors: Sarah Walker, - * Miran Grca, - * GH Cao, + * Authors: Sarah Walker, + * Miran Grca, + * GH Cao, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2020 GH Cao. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2020 GH Cao. */ #include #include @@ -246,7 +246,7 @@ joystick_get_device_name(raw_joystick_t *rawjoy, plat_joystick_t *joy, PRID_DEVI } void -joystick_init() +joystick_init(void) { UINT size = 0; atexit(joystick_close); @@ -316,7 +316,7 @@ end_loop: } void -joystick_close() +joystick_close(void) { RAWINPUTDEVICE ridev[2]; ridev[0].dwFlags = RIDEV_REMOVE; diff --git a/src/win/win_joystick_xinput.c b/src/win/win_joystick_xinput.c index 605626420..caf8f3452 100644 --- a/src/win/win_joystick_xinput.c +++ b/src/win/win_joystick_xinput.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Xinput joystick interface. + * Xinput joystick interface. * * * - * Authors: Sarah Walker, - * Miran Grca, - * GH Cao, + * Authors: Sarah Walker, + * Miran Grca, + * GH Cao, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2019 GH Cao. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2019 GH Cao. */ #include #define _USE_MATH_DEFINES diff --git a/src/win/win_keyboard.c b/src/win/win_keyboard.c index ae31c3ff6..6b7e00b57 100644 --- a/src/win/win_keyboard.c +++ b/src/win/win_keyboard.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Windows raw keyboard input handler. + * Windows raw keyboard input handler. * * * - * Author: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2018 Miran Grca. */ #define UNICODE #define _WIN32_WINNT 0x0501 diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c index 7695f28b2..8d8de6f53 100644 --- a/src/win/win_media_menu.c +++ b/src/win/win_media_menu.c @@ -79,10 +79,10 @@ media_menu_set_name_cassette(void) MENUITEMINFO mii = { 0 }; if (strlen(cassette_fname) == 0) - _swprintf(name, plat_get_string(IDS_2148), plat_get_string(IDS_2057)); + _swprintf(name, plat_get_string(IDS_2149), plat_get_string(IDS_2057)); else { mbstoc16s(fn, cassette_fname, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2148), fn); + _swprintf(name, plat_get_string(IDS_2149), fn); } mii.cbSize = sizeof(mii); @@ -99,11 +99,11 @@ media_menu_set_name_cartridge(int drive) MENUITEMINFO mii = { 0 }; if (strlen(cart_fns[drive]) == 0) { - _swprintf(name, plat_get_string(IDS_2150), + _swprintf(name, plat_get_string(IDS_2151), drive + 1, plat_get_string(IDS_2057)); } else { mbstoc16s(fn, cart_fns[drive], sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2150), + _swprintf(name, plat_get_string(IDS_2151), drive + 1, fn); } @@ -123,11 +123,11 @@ media_menu_set_name_floppy(int drive) mbstoc16s(temp, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); if (strlen(floppyfns[drive]) == 0) { - _swprintf(name, plat_get_string(IDS_2108), + _swprintf(name, plat_get_string(IDS_2109), drive + 1, temp, plat_get_string(IDS_2057)); } else { mbstoc16s(fn, floppyfns[drive], sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2108), + _swprintf(name, plat_get_string(IDS_2109), drive + 1, temp, fn); } @@ -209,11 +209,11 @@ media_menu_set_name_mo(int drive) temp = plat_get_string(id); if (strlen(mo_drives[drive].image_path) == 0) { - _swprintf(name, plat_get_string(IDS_2115), + _swprintf(name, plat_get_string(IDS_2116), drive + 1, temp, plat_get_string(IDS_2057)); } else { mbstoc16s(fn, mo_drives[drive].image_path, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2115), + _swprintf(name, plat_get_string(IDS_2116), drive + 1, temp, fn); } @@ -350,7 +350,7 @@ media_menu_update_mo(int id) } static void -media_menu_load_submenus() +media_menu_load_submenus(void) { memset(index_map, -1, sizeof(index_map)); @@ -428,7 +428,7 @@ is_valid_mo(int i) } void -media_menu_reset() +media_menu_reset(void) { /* Remove existing entries. */ int c = GetMenuItemCount(media_menu); @@ -488,7 +488,7 @@ media_menu_reset() /* Initializes the Media menu in the main menu bar. */ static void -media_menu_main_init() +media_menu_main_init(void) { HMENU hMenu; LPWSTR lpMenuName; @@ -510,7 +510,7 @@ media_menu_main_init() } void -media_menu_init() +media_menu_init(void) { /* Initialize the main menu bar menu */ media_menu_main_init(); @@ -535,7 +535,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (LOWORD(wParam) & 0xff00) { case IDM_CASSETTE_IMAGE_NEW: - ret = file_dlg_st(hwnd, IDS_2149, "", NULL, 1); + ret = file_dlg_st(hwnd, IDS_2150, "", NULL, 1); if (!ret) { if (strlen(openfilestring) == 0) cassette_mount(NULL, wp); @@ -565,7 +565,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) wp = 1; /* FALLTHROUGH */ case IDM_CASSETTE_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2149, cassette_fname, NULL, 0); + ret = file_dlg_st(hwnd, IDS_2150, cassette_fname, NULL, 0); if (!ret) { if (strlen(openfilestring) == 0) cassette_mount(NULL, wp); @@ -579,7 +579,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_CARTRIDGE_IMAGE: - ret = file_dlg_st(hwnd, IDS_2151, cart_fns[id], NULL, 0); + ret = file_dlg_st(hwnd, IDS_2152, cart_fns[id], NULL, 0); if (!ret) cartridge_mount(id, openfilestring, wp); break; @@ -596,7 +596,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) wp = 1; /* FALLTHROUGH */ case IDM_FLOPPY_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2109, floppyfns[id], NULL, 0); + ret = file_dlg_st(hwnd, IDS_2110, floppyfns[id], NULL, 0); if (!ret) floppy_mount(id, openfilestring, wp); break; @@ -632,7 +632,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_CDROM_IMAGE: - if (!file_dlg_st(hwnd, IDS_2140, cdrom[id].is_dir ? NULL : cdrom[id].image_path, NULL, 0)) { + if (!file_dlg_st(hwnd, IDS_2141, cdrom[id].is_dir ? NULL : cdrom[id].image_path, NULL, 0)) { cdrom_mount(id, openfilestring); } break; @@ -687,7 +687,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) wp = 1; /* FALLTHROUGH */ case IDM_MO_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2116, mo_drives[id].image_path, NULL, 0); + ret = file_dlg_st(hwnd, IDS_2117, mo_drives[id].image_path, NULL, 0); if (!ret) mo_mount(id, openfilestring, wp); break; diff --git a/src/win/win_mouse.c b/src/win/win_mouse.c index 25d3c593b..4490328a9 100644 --- a/src/win/win_mouse.c +++ b/src/win/win_mouse.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * RawInput mouse interface. + * RawInput mouse interface. * - * Version: @(#)win_mouse_rawinput.cpp 1.0.0 2019/3/19 * - * Authors: Sarah Walker, - * Miran Grca, - * GH Cao, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - * Copyright 2019 GH Cao. + * Authors: Sarah Walker, + * Miran Grca, + * GH Cao, + * + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2019 GH Cao. */ #include #include diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index 95cde3176..33807a78e 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handle the New Floppy Image dialog. + * Handle the New Floppy Image dialog. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2019 Miran Grca. + * Copyright 2016-2019 Miran Grca. */ #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -773,7 +773,7 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) return TRUE; case IDC_CFILE: - if (!file_dlg_w(hdlg, plat_get_string(is_mo ? IDS_2139 : (is_zip ? IDS_2055 : IDS_2062)), L"", NULL, 1)) { + if (!file_dlg_w(hdlg, plat_get_string(is_mo ? IDS_2140 : (is_zip ? IDS_2055 : IDS_2062)), L"", NULL, 1)) { if (!wcschr(wopenfilestring, L'.')) { if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { twcs = &wopenfilestring[wcslen(wopenfilestring)]; diff --git a/src/win/win_opendir.c b/src/win/win_opendir.c index 540083584..a3537a546 100644 --- a/src/win/win_opendir.c +++ b/src/win/win_opendir.c @@ -1,21 +1,21 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implementation POSIX OpenDir(3) and friends for Win32 API. + * Implementation POSIX OpenDir(3) and friends for Win32 API. * - * Based on old original code @(#)dir_win32.c 1.2.0 2007/04/19 + * Based on old original code @(#)dir_win32.c 1.2.0 2007/04/19 * * * - * Author: Fred N. van Kempen, + * Authors: Fred N. van Kempen, * - * Copyright 1998-2007 MicroWalt Corporation - * Copyright 2017 Fred N. van Kempen + * Copyright 1998-2007 MicroWalt Corporation + * Copyright 2017 Fred N. van Kempen */ #include #include diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index b473ce18f..d9a492927 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Rendering module for OpenGL + * Rendering module for OpenGL * - * TODO: More shader features - * - scaling - * - multipass - * - previous frames - * (UI) options - * More error handling + * TODO: More shader features + * - scaling + * - multipass + * - previous frames + * (UI) options + * More error handling * - * Authors: Teemu Korhonen + * Authors: Teemu Korhonen * - * Copyright 2021 Teemu Korhonen + * Copyright 2021 Teemu Korhonen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -438,15 +438,15 @@ render_and_swap(gl_identifiers *gl) * Keeps the thread sleeping until closing. */ static void -opengl_fail() +opengl_fail(void) { if (window != NULL) { SDL_DestroyWindow(window); window = NULL; } - wchar_t *message = plat_get_string(IDS_2152); - wchar_t *header = plat_get_string(IDS_2153); + wchar_t *message = plat_get_string(IDS_2153); + wchar_t *header = plat_get_string(IDS_2154); MessageBox(parent, header, message, MB_OK); WaitForSingleObject(sync_objects.closing, INFINITE); diff --git a/src/win/win_opengl_glslp.c b/src/win/win_opengl_glslp.c index 10278b799..c3d40a56e 100644 --- a/src/win/win_opengl_glslp.c +++ b/src/win/win_opengl_glslp.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * File parser for .glslp and .glsl shader files - * in the format of libretro. + * File parser for .glslp and .glsl shader files + * in the format of libretro. * - * TODO: Read .glslp files for multipass shaders and settings. + * TODO: Read .glslp files for multipass shaders and settings. * - * Authors: Teemu Korhonen + * Authors: Teemu Korhonen * - * Copyright 2021 Teemu Korhonen + * Copyright 2021 Teemu Korhonen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -240,7 +240,7 @@ load_custom_shaders(const char *path) * @return Shader program identifier. */ GLuint -load_default_shaders() +load_default_shaders(void) { GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); diff --git a/src/win/win_preferences.c b/src/win/win_preferences.c index 227b52e35..17cfd693c 100644 --- a/src/win/win_preferences.c +++ b/src/win/win_preferences.c @@ -1,17 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handle the dialog for changing the program's language and other global settings. + * Handle the dialog for changing the program's language and other global settings. * * - * Authors: Laci bá' * - * Copyright 2021 Laci bá' + * Authors: Laci bá' + * + * Copyright 2021 Laci bá' */ #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -86,7 +87,7 @@ preferences_fill_iconsets(HWND hdlg) /* Add the default one */ wchar_t buffer[512] = L"("; - wcscat(buffer, plat_get_string(IDS_2090)); + wcscat(buffer, plat_get_string(IDS_DEFAULT)); wcscat(buffer, L")"); SendMessage(icon_combo, CB_RESETCONTENT, 0, 0); diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index cb3b51e77..5c133524a 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -1,42 +1,42 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Rendering module for libSDL2 + * Rendering module for libSDL2 * - * NOTE: Given all the problems reported with FULLSCREEN use of SDL, - * we will not use that, but, instead, use a new window which - * coverrs the entire desktop. + * NOTE: Given all the problems reported with FULLSCREEN use of SDL, + * we will not use that, but, instead, use a new window which + * coverrs the entire desktop. * * * - * Authors: Fred N. van Kempen, - * Michael Drüing, + * Authors: Fred N. van Kempen, + * Michael Drüing, * - * Copyright 2018-2020 Fred N. van Kempen. - * Copyright 2018-2020 Michael Drüing. + * Copyright 2018-2020 Fred N. van Kempen. + * Copyright 2018-2020 Michael Drüing. * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 724222bb0..afb283adc 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -1,22 +1,22 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Windows 86Box Settings dialog handler. + * Windows 86Box Settings dialog handler. * * * - * Authors: Miran Grca, - * David Hrdlička, + * Authors: Miran Grca, + * David Hrdlička, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 David Hrdlička. - * Copyright 2021 Laci bá' - * Copyright 2021-2022 Jasmine Iwanek. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018,2019 David Hrdlička. + * Copyright 2021 Laci bá' + * Copyright 2021-2022 Jasmine Iwanek. */ #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -74,8 +74,13 @@ #include "../disk/minivhd/minivhd.h" #include "../disk/minivhd/minivhd_util.h" -/* Icon, Bus, File, C, H, S, Size */ -#define C_COLUMNS_HARD_DISKS 6 +/* Icon, Bus, File, C, H, S, Size, Speed */ +#define C_COLUMNS_HARD_DISKS 7 + +#define C_COLUMNS_FLOPPY_DRIVES 3 +#define C_COLUMNS_CDROM_DRIVES 3 +#define C_COLUMNS_MO_DRIVES 2 +#define C_COLUMNS_ZIP_DRIVES 2 static int first_cat = 0; @@ -88,7 +93,7 @@ static int temp_dynarec; #endif /* Video category */ -static int temp_gfxcard, temp_ibm8514, temp_voodoo, temp_xga; +static int temp_gfxcard, temp_gfxcard_2, temp_ibm8514, temp_voodoo, temp_xga; /* Input devices category */ static int temp_mouse, temp_joystick; @@ -225,7 +230,7 @@ settings_listview_select(HWND hdlg, int id, int selection) } static void -settings_process_messages() +settings_process_messages(void) { MSG msg; while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { @@ -319,10 +324,11 @@ win_settings_init(void) temp_sync = time_sync; /* Video category */ - temp_gfxcard = gfxcard; - temp_voodoo = voodoo_enabled; - temp_ibm8514 = ibm8514_enabled; - temp_xga = xga_enabled; + temp_gfxcard = gfxcard; + temp_gfxcard_2 = gfxcard_2; + temp_voodoo = voodoo_enabled; + temp_ibm8514 = ibm8514_enabled; + temp_xga = xga_enabled; /* Input devices category */ temp_mouse = mouse_type; @@ -446,6 +452,7 @@ win_settings_changed(void) /* Video category */ i = i || (gfxcard != temp_gfxcard); + i = i || (gfxcard_2 != temp_gfxcard_2); i = i || (voodoo_enabled != temp_voodoo); i = i || (ibm8514_enabled != temp_ibm8514); i = i || (xga_enabled != temp_xga); @@ -538,6 +545,7 @@ win_settings_save(void) /* Video category */ gfxcard = temp_gfxcard; + gfxcard_2 = temp_gfxcard_2; voodoo_enabled = temp_voodoo; ibm8514_enabled = temp_ibm8514; xga_enabled = temp_xga; @@ -595,7 +603,7 @@ win_settings_save(void) /* Removable devices category */ memcpy(cdrom, temp_cdrom, CDROM_NUM * sizeof(cdrom_t)); for (i = 0; i < CDROM_NUM; i++) { - cdrom[i].is_dir = 0; + cdrom[i].is_dir = 0; cdrom[i].priv = NULL; cdrom[i].ops = NULL; cdrom[i].image = NULL; @@ -789,7 +797,7 @@ win_settings_machine_recalc_machine(HWND hdlg) SendMessage(h, UDM_SETPOS, 0, temp_mem_size); h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_2088)); + SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_KB)); } else { /* MB granularity */ h = GetDlgItem(hdlg, IDC_MEMSPIN); @@ -803,7 +811,7 @@ win_settings_machine_recalc_machine(HWND hdlg) SendMessage(h, UDM_SETPOS, 0, temp_mem_size >> 10); h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_2086)); + SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_MB)); } settings_enable_window(hdlg, IDC_MEMSPIN, machine_get_min_ram(temp_machine) != machine_get_max_ram(temp_machine)); @@ -886,9 +894,9 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) c++; } - settings_add_string(hdlg, IDC_COMBO_WS, win_get_string(IDS_2090)); - for (c = 0; c < 8; c++) { - wsprintf(lptsTemp, plat_get_string(IDS_2091), c); + settings_add_string(hdlg, IDC_COMBO_WS, win_get_string(IDS_DEFAULT)); + for (c = 0; c < 8; c++) { /* TODO */ + wsprintf(lptsTemp, plat_get_string(IDS_WS), c); settings_add_string(hdlg, IDC_COMBO_WS, (LPARAM) lptsTemp); } @@ -1034,7 +1042,7 @@ generate_device_name(const device_t *device, char *internal_name, int bus) if (!strcmp(internal_name, "none")) { /* Translate "None". */ - wtemp = (WCHAR *) win_get_string(IDS_2103); + wtemp = (WCHAR *) win_get_string(IDS_2104); memcpy(device_name, wtemp, (wcslen(wtemp) + 1) * sizeof(WCHAR)); return; } else if (!strcmp(internal_name, "internal")) @@ -1057,6 +1065,7 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_INITDIALOG: + // Primary Video Card settings_reset_content(hdlg, IDC_COMBO_VIDEO); while (1) { @@ -1072,10 +1081,10 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2103)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2118)); + if (c == 0) // "None" + settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2104)); + else if (c == 1) // "Internal" + settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2119)); else settings_add_string(hdlg, IDC_COMBO_VIDEO, (LPARAM) device_name); settings_list_to_device[0][d] = c; @@ -1093,6 +1102,44 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) e = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(e)); + // Secondary Video Card + c = 0; + settings_reset_content(hdlg, IDC_COMBO_VIDEO_2); + + while (1) { + /* Skip "internal" if machine doesn't have it. */ + if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) { + c++; + continue; + } + + generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1); + + if (!device_name[0]) + break; + + if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) { + if (c == 0) // "None" + settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2104)); + else if (c == 1) // "Internal" + settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2119)); + else if (video_card_get_flags(c) != video_card_get_flags(gfxcard)) + settings_add_string(hdlg, IDC_COMBO_VIDEO_2, (LPARAM) device_name); + settings_list_to_device[1][d] = c; + if ((c == 0) || (c == temp_gfxcard_2)) + settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO_2, d); + d++; + } + + c++; + + settings_process_messages(); + } + + settings_enable_window(hdlg, IDC_COMBO_VIDEO_2, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY)); + e = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; + settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(e)); + settings_enable_window(hdlg, IDC_CHECK_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI)); settings_set_check(hdlg, IDC_CHECK_VOODOO, temp_voodoo); settings_enable_window(hdlg, IDC_BUTTON_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI) && temp_voodoo); @@ -1113,6 +1160,11 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(temp_gfxcard)); break; + case IDC_COMBO_VIDEO_2: + temp_gfxcard_2 = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; + settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(temp_gfxcard_2)); + break; + case IDC_CHECK_VOODOO: temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO); settings_enable_window(hdlg, IDC_BUTTON_VOODOO, temp_voodoo); @@ -1143,14 +1195,20 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) temp_gfxcard = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; temp_deviceconfig |= deviceconfig_open(hdlg, (void *) video_card_getdevice(temp_gfxcard)); break; + + case IDC_CONFIGURE_VID_2: + temp_gfxcard_2 = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; + temp_deviceconfig |= deviceconfig_open(hdlg, (void *) video_card_getdevice(temp_gfxcard_2)); + break; } return FALSE; case WM_SAVESETTINGS: - temp_gfxcard = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; - temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO); - temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514); - temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA); + temp_gfxcard = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; + temp_gfxcard_2 = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; + temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO); + temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514); + temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA); default: return FALSE; @@ -1189,9 +1247,9 @@ win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (mouse_valid(c, temp_machine)) { generate_device_name(mouse_get_device(c), mouse_get_internal_name(c), 0); if (c == 0) - settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2104)); else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2118)); + settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2119)); else settings_add_string(hdlg, IDC_COMBO_MOUSE, (LPARAM) device_name); settings_list_to_device[0][d] = c; @@ -1318,9 +1376,9 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (device_is_valid(sound_dev, temp_machine)) { if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SOUND, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_SOUND, win_get_string(IDS_2104)); else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_SOUND, win_get_string(IDS_2118)); + settings_add_string(hdlg, IDC_COMBO_SOUND, win_get_string(IDS_2119)); else settings_add_string(hdlg, IDC_COMBO_SOUND, (LPARAM) device_name); settings_list_to_device[0][d] = c; @@ -1346,7 +1404,7 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (midi_out_device_available(c)) { if (c == 0) - settings_add_string(hdlg, IDC_COMBO_MIDI_OUT, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_MIDI_OUT, win_get_string(IDS_2104)); else settings_add_string(hdlg, IDC_COMBO_MIDI_OUT, (LPARAM) device_name); settings_list_to_midi[d] = c; @@ -1370,7 +1428,7 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (midi_in_device_available(c)) { if (c == 0) - settings_add_string(hdlg, IDC_COMBO_MIDI_IN, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_MIDI_IN, win_get_string(IDS_2104)); else settings_add_string(hdlg, IDC_COMBO_MIDI_IN, (LPARAM) device_name); settings_list_to_midi_in[d] = c; @@ -1531,7 +1589,7 @@ win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; if (c == 0) - settings_add_string(hdlg, IDC_COMBO_LPT1 + i, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_LPT1 + i, win_get_string(IDS_2104)); else { mbstowcs(lptsTemp, s, strlen(s) + 1); settings_add_string(hdlg, IDC_COMBO_LPT1 + i, (LPARAM) lptsTemp); @@ -1619,9 +1677,9 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (device_is_valid(hdc_dev, temp_machine)) { if (c == 0) - settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2104)); else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2118)); + settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2119)); else settings_add_string(hdlg, IDC_COMBO_HDC, (LPARAM) device_name); settings_list_to_hdc[d] = c; @@ -1651,7 +1709,7 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (device_is_valid(fdc_dev, temp_machine)) { if (c == 0) - settings_add_string(hdlg, IDC_COMBO_FDC, win_get_string(IDS_2118)); + settings_add_string(hdlg, IDC_COMBO_FDC, win_get_string(IDS_2119)); else settings_add_string(hdlg, IDC_COMBO_FDC, (LPARAM) device_name); settings_list_to_fdc[d] = c; @@ -1683,7 +1741,7 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (device_is_valid(scsi_dev, temp_machine)) { for (e = 0; e < SCSI_BUS_MAX; e++) { if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, win_get_string(IDS_2104)); else settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, (LPARAM) device_name); @@ -1836,7 +1894,7 @@ win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (network_card_available(c) && device_is_valid(network_card_getdevice(c), temp_machine)) { if (c == 0) - settings_add_string(hdlg, IDC_COMBO_NET, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_NET, win_get_string(IDS_2104)); else settings_add_string(hdlg, IDC_COMBO_NET, (LPARAM) device_name); settings_list_to_device[0][d] = c; @@ -1905,7 +1963,7 @@ win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) } static void -normalize_hd_list() +normalize_hd_list(void) { hard_disk_t ihdd[HDD_NUM]; int i, j; @@ -2159,7 +2217,7 @@ win_settings_hard_disks_update_item(HWND hdlg, int i, int column) lvI.iSubItem = column; lvI.iItem = i; - if (column == 0) { + if (column == 0) { /* Bus */ switch (temp_hdd[i].bus) { case HDD_BUS_MFM: wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); @@ -2182,29 +2240,33 @@ win_settings_hard_disks_update_item(HWND hdlg, int i, int column) } lvI.pszText = szText; lvI.iImage = 0; - } else if (column == 1) { + } else if (column == 1) { /* File */ if (!strnicmp(temp_hdd[i].fn, usr_path, strlen(usr_path))) mbstoc16s(szText, temp_hdd[i].fn + strlen(usr_path), sizeof_w(szText)); else mbstoc16s(szText, temp_hdd[i].fn, sizeof_w(szText)); lvI.pszText = szText; lvI.iImage = 0; - } else if (column == 2) { + } else if (column == 2) { /* Cylinders */ wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); lvI.pszText = szText; lvI.iImage = 0; - } else if (column == 3) { + } else if (column == 3) { /* Heads */ wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); lvI.pszText = szText; lvI.iImage = 0; - } else if (column == 4) { + } else if (column == 4) { /* Sectors */ wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); lvI.pszText = szText; lvI.iImage = 0; - } else if (column == 5) { + } else if (column == 5) { /* Size (MB) */ wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); lvI.pszText = szText; lvI.iImage = 0; + } else if (column == 6) { /* Speed (RPM) */ + mbstoc16s(szText, hdd_preset_getname(temp_hdd[i].speed_preset), sizeof_w(szText)); + lvI.pszText = szText; + lvI.iImage = 0; } if (ListView_SetItem(hwndList, &lvI) == -1) @@ -2233,6 +2295,8 @@ win_settings_hard_disks_recalc_list(HWND hdlg) if (temp_hdd[i].bus > 0) { hdc_id_to_listview_index[i] = j; lvI.iSubItem = 0; + + /* Bus */ switch (temp_hdd[i].bus) { case HDD_BUS_MFM: wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); @@ -2260,6 +2324,7 @@ win_settings_hard_disks_recalc_list(HWND hdlg) if (ListView_InsertItem(hwndList, &lvI) == -1) return FALSE; + /* File */ lvI.iSubItem = 1; if (!strnicmp(temp_hdd[i].fn, usr_path, strlen(usr_path))) mbstoc16s(szText, temp_hdd[i].fn + strlen(usr_path), sizeof_w(szText)); @@ -2270,6 +2335,7 @@ win_settings_hard_disks_recalc_list(HWND hdlg) if (ListView_SetItem(hwndList, &lvI) == -1) return FALSE; + /* Cylinders */ lvI.iSubItem = 2; wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); lvI.pszText = szText; @@ -2277,6 +2343,7 @@ win_settings_hard_disks_recalc_list(HWND hdlg) if (ListView_SetItem(hwndList, &lvI) == -1) return FALSE; + /* Heads */ lvI.iSubItem = 3; wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); lvI.pszText = szText; @@ -2284,6 +2351,7 @@ win_settings_hard_disks_recalc_list(HWND hdlg) if (ListView_SetItem(hwndList, &lvI) == -1) return FALSE; + /* Sectors */ lvI.iSubItem = 4; wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); lvI.pszText = szText; @@ -2291,10 +2359,19 @@ win_settings_hard_disks_recalc_list(HWND hdlg) if (ListView_SetItem(hwndList, &lvI) == -1) return FALSE; + /* Size (MB) */ lvI.iSubItem = 5; wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); lvI.pszText = szText; + if (ListView_SetItem(hwndList, &lvI) == -1) + return FALSE; + + /* Speed (RPM) */ + lvI.iSubItem = 6; + mbstoc16s(szText, hdd_preset_getname(temp_hdd[i].speed_preset), sizeof_w(szText)); + lvI.pszText = szText; + if (ListView_SetItem(hwndList, &lvI) == -1) return FALSE; @@ -2308,11 +2385,27 @@ win_settings_hard_disks_recalc_list(HWND hdlg) return TRUE; } +#define C_COLUMNS_HARD_DISKS_BUS 104 +#define C_COLUMNS_HARD_DISKS_FILE 254 +#define C_COLUMNS_HARD_DISKS_CYLS 50 +#define C_COLUMNS_HARD_DISKS_HEADS 26 +#define C_COLUMNS_HARD_DISKS_SECT 32 +#define C_COLUMNS_HARD_DISKS_SIZE 50 +#define C_COLUMNS_HARD_DISKS_SPEED 100 + static void win_settings_hard_disks_resize_columns(HWND hdlg) { /* Bus, File, Cylinders, Heads, Sectors, Size */ - int iCol, width[C_COLUMNS_HARD_DISKS] = { 104, 354, 50, 26, 32, 50 }; + int iCol, width[C_COLUMNS_HARD_DISKS] = { + C_COLUMNS_HARD_DISKS_BUS, + C_COLUMNS_HARD_DISKS_FILE, + C_COLUMNS_HARD_DISKS_CYLS, + C_COLUMNS_HARD_DISKS_HEADS, + C_COLUMNS_HARD_DISKS_SECT, + C_COLUMNS_HARD_DISKS_SIZE, + C_COLUMNS_HARD_DISKS_SPEED + }; int total = 0; HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); RECT r; @@ -2338,31 +2431,35 @@ win_settings_hard_disks_init_columns(HWND hdlg) for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) { lvc.iSubItem = iCol; - lvc.pszText = plat_get_string(IDS_2081 + iCol); + lvc.pszText = plat_get_string(IDS_BUS + iCol); switch (iCol) { case 0: /* Bus */ - lvc.cx = 104; + lvc.cx = C_COLUMNS_HARD_DISKS_BUS; lvc.fmt = LVCFMT_LEFT; break; case 1: /* File */ - lvc.cx = 354; + lvc.cx = C_COLUMNS_HARD_DISKS_FILE; lvc.fmt = LVCFMT_LEFT; break; case 2: /* Cylinders */ - lvc.cx = 50; + lvc.cx = C_COLUMNS_HARD_DISKS_CYLS; lvc.fmt = LVCFMT_RIGHT; break; case 3: /* Heads */ - lvc.cx = 26; + lvc.cx = C_COLUMNS_HARD_DISKS_HEADS; lvc.fmt = LVCFMT_RIGHT; break; case 4: /* Sectors */ - lvc.cx = 32; + lvc.cx = C_COLUMNS_HARD_DISKS_SECT; lvc.fmt = LVCFMT_RIGHT; break; - case 5: /* Size (MB) 8 */ - lvc.cx = 50; + case 5: /* Size (MB) */ + lvc.cx = C_COLUMNS_HARD_DISKS_SIZE; + lvc.fmt = LVCFMT_RIGHT; + break; + case 6: /* Speed (RPM) */ + lvc.cx = C_COLUMNS_HARD_DISKS_SPEED; lvc.fmt = LVCFMT_RIGHT; break; } @@ -2395,7 +2492,7 @@ set_edit_box_contents(HWND hdlg, int id, uint32_t val) WCHAR szText[256]; h = GetDlgItem(hdlg, id); - wsprintf(szText, plat_get_string(IDS_2106), val); + wsprintf(szText, plat_get_string(IDS_2107), val); SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); } @@ -2426,7 +2523,7 @@ hdconf_initialize_hdt_combo(HWND hdlg) for (i = 0; i < 127; i++) { temp_size = ((uint64_t) hdd_table[i][0]) * hdd_table[i][1] * hdd_table[i][2]; size_mb = (uint32_t) (temp_size >> 11LL); - wsprintf(szText, plat_get_string(IDS_2107), size_mb, hdd_table[i][0], hdd_table[i][1], hdd_table[i][2]); + wsprintf(szText, plat_get_string(IDS_2108), size_mb, hdd_table[i][0], hdd_table[i][1], hdd_table[i][2]); settings_add_string(hdlg, IDC_COMBO_HD_TYPE, (LPARAM) szText); if ((tracks == (int) hdd_table[i][0]) && (hpc == (int) hdd_table[i][1]) && (spt == (int) hdd_table[i][2])) selection = i; @@ -2729,7 +2826,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM /* Make sure no file name is allowed with removable SCSI hard disks. */ if (wcslen(hd_file_name) == 0) { hdd_ptr->bus = HDD_BUS_DISABLED; - settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4112); + settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2131, (wchar_t *) IDS_4112); return TRUE; } @@ -2772,13 +2869,13 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM } img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT); - if (img_format < 3) { + if (img_format < IMG_FMT_VHD_FIXED) { f = _wfopen(hd_file_name, L"wb"); } else { f = (FILE *) 0; } - if (img_format == 1) { /* HDI file */ + if (img_format == IMG_FMT_HDI) { /* HDI file */ if (size >= 0x100000000ll) { fclose(f); settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4104); @@ -2796,27 +2893,27 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM for (i = 0; i < 0x3f8; i++) fwrite(&zero, 1, 4, f); - } else if (img_format == 2) { /* HDX file */ - fwrite(&signature, 1, 8, f); /* 00000000: Signature */ - fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ - } else if (img_format >= 3) { /* VHD file */ + } else if (img_format == IMG_FMT_HDX) { /* HDX file */ + fwrite(&signature, 1, 8, f); /* 00000000: Signature */ + fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ + fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ + } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ MVHDGeom _86box_geometry; block_size = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE) == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; switch (img_format) { - case 3: + case IMG_FMT_VHD_FIXED: vhd_progress_hdlg = hdlg; _86box_geometry = create_drive_vhd_fixed(hd_file_name_multibyte, tracks, hpc, spt); break; - case 4: + case IMG_FMT_VHD_DYNAMIC: _86box_geometry = create_drive_vhd_dynamic(hd_file_name_multibyte, tracks, hpc, spt, block_size); break; - case 5: + case IMG_FMT_VHD_DIFF: if (file_dlg_w(hdlg, plat_get_string(IDS_4130), L"", plat_get_string(IDS_4131), 0)) { return TRUE; } @@ -2824,7 +2921,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM break; } - if (img_format != 5) + if (img_format != IMG_FMT_VHD_DIFF) settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117); hdd_ptr->tracks = _86box_geometry.cyl; @@ -3269,7 +3366,7 @@ hdd_add_file_open_error: img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT); no_update = 1; - if (img_format == 5) { /* They switched to a diff VHD; disable the geometry fields. */ + if (img_format == IMG_FMT_VHD_DIFF) { /* They switched to a diff VHD; disable the geometry fields. */ settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE); set_edit_box_text_contents(hdlg, IDC_EDIT_HD_SPT, L"(N/A)"); settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE); @@ -3305,7 +3402,7 @@ hdd_add_file_open_error: } no_update = 0; - if (img_format == 4 || img_format == 5) { /* For dynamic and diff VHDs, show the block size dropdown. */ + if (img_format == IMG_FMT_VHD_DYNAMIC || img_format == IMG_FMT_VHD_DIFF) { /* For dynamic and diff VHDs, show the block size dropdown. */ settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, TRUE); settings_show_window(hdlg, IDT_BLOCK_SIZE, TRUE); } else { /* Hide it otherwise. */ @@ -3627,7 +3724,7 @@ win_settings_cdrom_drives_recalc_list(HWND hdlg) lvI.iSubItem = 1; if (temp_cdrom[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2103); + lvI.pszText = plat_get_string(IDS_2104); else { wsprintf(szText, L"%ix", temp_cdrom[i].speed); lvI.pszText = szText; @@ -3691,7 +3788,7 @@ win_settings_mo_drives_recalc_list(HWND hdlg) lvI.iSubItem = 1; if (temp_mo_drives[i].bus_type == MO_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2103); + lvI.pszText = plat_get_string(IDS_2104); else { memset(szType, 0, 30); memcpy(szType, mo_drive_types[temp_mo_drives[i].type].vendor, 8); @@ -3763,22 +3860,30 @@ win_settings_zip_drives_recalc_list(HWND hdlg) return TRUE; } +#define C_COLUMNS_FLOPPY_DRIVES_TYPE 292 +#define C_COLUMNS_FLOPPY_DRIVES_TURBO 58 +#define C_COLUMNS_FLOPPY_DRIVES_BPB 89 + static void win_settings_floppy_drives_resize_columns(HWND hdlg) { - int iCol, width[3] = { 292, 58, 89 }; + int iCol, width[C_COLUMNS_FLOPPY_DRIVES] = { + C_COLUMNS_FLOPPY_DRIVES_TYPE, + C_COLUMNS_FLOPPY_DRIVES_TURBO, + C_COLUMNS_FLOPPY_DRIVES_BPB + }; int total = 0; HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); RECT r; GetWindowRect(hwndList, &r); - for (iCol = 0; iCol < 2; iCol++) { + for (iCol = 0; iCol < C_COLUMNS_FLOPPY_DRIVES; iCol++) { width[iCol] = MulDiv(width[iCol], dpi, 96); total += width[iCol]; ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96)); } - width[2] = (r.right - r.left) - 4 - total; - ListView_SetColumnWidth(hwndList, 2, width[2]); + width[C_COLUMNS_FLOPPY_DRIVES - 1] = (r.right - r.left) - 4 - total; + ListView_SetColumnWidth(hwndList, 2, width[C_COLUMNS_FLOPPY_DRIVES - 1]); } static BOOL @@ -3789,28 +3894,31 @@ win_settings_floppy_drives_init_columns(HWND hdlg) lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + /* Type */ lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2092); + lvc.pszText = plat_get_string(IDS_TYPE); - lvc.cx = 292; + lvc.cx = C_COLUMNS_FLOPPY_DRIVES_TYPE; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) return FALSE; + /* Turbo */ lvc.iSubItem = 1; lvc.pszText = plat_get_string(IDS_2059); - lvc.cx = 58; + lvc.cx = C_COLUMNS_FLOPPY_DRIVES_TURBO; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) return FALSE; + /* Check BPB */ lvc.iSubItem = 2; - lvc.pszText = plat_get_string(IDS_2087); + lvc.pszText = plat_get_string(IDS_BPB); - lvc.cx = 89; + lvc.cx = C_COLUMNS_FLOPPY_DRIVES_BPB; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 2, &lvc) == -1) @@ -3820,22 +3928,30 @@ win_settings_floppy_drives_init_columns(HWND hdlg) return TRUE; } +#define C_COLUMNS_CDROM_DRIVES_BUS 292 +#define C_COLUMNS_CDROM_DRIVES_SPEED 58 +#define C_COLUMNS_CDROM_DRIVES_EARLIER 89 + static void win_settings_cdrom_drives_resize_columns(HWND hdlg) { - int iCol, width[3] = { 292, 58, 89 }; + int iCol, width[C_COLUMNS_CDROM_DRIVES] = { + C_COLUMNS_CDROM_DRIVES_BUS, + C_COLUMNS_CDROM_DRIVES_SPEED, + C_COLUMNS_CDROM_DRIVES_EARLIER + }; int total = 0; HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); RECT r; GetWindowRect(hwndList, &r); - for (iCol = 0; iCol < 2; iCol++) { + for (iCol = 0; iCol < C_COLUMNS_CDROM_DRIVES; iCol++) { width[iCol] = MulDiv(width[iCol], dpi, 96); total += width[iCol]; ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96)); } - width[2] = (r.right - r.left) - 4 - total; - ListView_SetColumnWidth(hwndList, 2, width[2]); + width[C_COLUMNS_CDROM_DRIVES - 1] = (r.right - r.left) - 4 - total; + ListView_SetColumnWidth(hwndList, 2, width[C_COLUMNS_CDROM_DRIVES - 1]); } static BOOL @@ -3846,28 +3962,31 @@ win_settings_cdrom_drives_init_columns(HWND hdlg) lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + /* Bus */ lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2081); + lvc.pszText = plat_get_string(IDS_BUS); - lvc.cx = 292; + lvc.cx = C_COLUMNS_CDROM_DRIVES_BUS; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) return FALSE; + /* Speed */ lvc.iSubItem = 1; lvc.pszText = plat_get_string(IDS_2053); - lvc.cx = 58; + lvc.cx = C_COLUMNS_CDROM_DRIVES_SPEED; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) return FALSE; + /* Earlier drive */ lvc.iSubItem = 2; - lvc.pszText = plat_get_string(IDS_2161); + lvc.pszText = plat_get_string(IDS_2162); - lvc.cx = 89; + lvc.cx = C_COLUMNS_CDROM_DRIVES_EARLIER; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 2, &lvc) == -1) @@ -3877,18 +3996,24 @@ win_settings_cdrom_drives_init_columns(HWND hdlg) return TRUE; } +#define C_COLUMNS_MO_DRIVES_BUS 292 +#define C_COLUMNS_MO_DRIVES_TYPE 147 + static void win_settings_mo_drives_resize_columns(HWND hdlg) { - int width[2] = { 292, 147 }; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); + int width[C_COLUMNS_MO_DRIVES] = { + C_COLUMNS_MO_DRIVES_BUS, + C_COLUMNS_MO_DRIVES_TYPE + }; + HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); RECT r; GetWindowRect(hwndList, &r); width[0] = MulDiv(width[0], dpi, 96); ListView_SetColumnWidth(hwndList, 0, MulDiv(width[0], dpi, 96)); - width[1] = (r.right - r.left) - 4 - width[0]; - ListView_SetColumnWidth(hwndList, 1, width[1]); + width[C_COLUMNS_MO_DRIVES - 1] = (r.right - r.left) - 4 - width[0]; + ListView_SetColumnWidth(hwndList, 1, width[C_COLUMNS_MO_DRIVES - 1]); } static BOOL @@ -3899,19 +4024,21 @@ win_settings_mo_drives_init_columns(HWND hdlg) lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + /* Bus */ lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2081); + lvc.pszText = plat_get_string(IDS_BUS); - lvc.cx = 292; + lvc.cx = C_COLUMNS_MO_DRIVES_BUS; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) return FALSE; + /* Type */ lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2092); + lvc.pszText = plat_get_string(IDS_TYPE); - lvc.cx = 147; + lvc.cx = C_COLUMNS_MO_DRIVES_TYPE; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) @@ -3921,18 +4048,24 @@ win_settings_mo_drives_init_columns(HWND hdlg) return TRUE; } +#define C_COLUMNS_ZIP_DRIVES_BUS 292 +#define C_COLUMNS_ZIP_DRIVES_TYPE 147 + static void win_settings_zip_drives_resize_columns(HWND hdlg) { - int width[2] = { 292, 147 }; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); + int width[C_COLUMNS_MO_DRIVES] = { + C_COLUMNS_ZIP_DRIVES_BUS, + C_COLUMNS_ZIP_DRIVES_TYPE + }; + HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); RECT r; GetWindowRect(hwndList, &r); width[0] = MulDiv(width[0], dpi, 96); ListView_SetColumnWidth(hwndList, 0, MulDiv(width[0], dpi, 96)); - width[1] = (r.right - r.left) - 4 - width[0]; - ListView_SetColumnWidth(hwndList, 1, width[1]); + width[C_COLUMNS_ZIP_DRIVES - 1] = (r.right - r.left) - 4 - width[0]; + ListView_SetColumnWidth(hwndList, 1, width[C_COLUMNS_ZIP_DRIVES - 1]); } static BOOL @@ -3943,19 +4076,21 @@ win_settings_zip_drives_init_columns(HWND hdlg) lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + /* Bus */ lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2081); + lvc.pszText = plat_get_string(IDS_BUS); - lvc.cx = 292; + lvc.cx = C_COLUMNS_ZIP_DRIVES_BUS; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) return FALSE; + /* Type */ lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2092); + lvc.pszText = plat_get_string(IDS_TYPE); - lvc.cx = 147; + lvc.cx = C_COLUMNS_ZIP_DRIVES_TYPE; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) @@ -4064,7 +4199,7 @@ win_settings_cdrom_drives_update_item(HWND hdlg, int i) lvI.iSubItem = 1; if (temp_cdrom[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2103); + lvI.pszText = plat_get_string(IDS_2104); else { wsprintf(szText, L"%ix", temp_cdrom[i].speed); lvI.pszText = szText; @@ -4096,6 +4231,7 @@ win_settings_mo_drives_update_item(HWND hdlg, int i) lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; lvI.stateMask = lvI.iSubItem = lvI.state = 0; + /* Bus */ lvI.iSubItem = 0; lvI.iItem = i; @@ -4122,9 +4258,10 @@ win_settings_mo_drives_update_item(HWND hdlg, int i) if (ListView_SetItem(hwndList, &lvI) == -1) return; + /* Type */ lvI.iSubItem = 1; if (temp_mo_drives[i].bus_type == MO_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2103); + lvI.pszText = plat_get_string(IDS_2104); else { memset(szType, 0, 30); memcpy(szType, mo_drive_types[temp_mo_drives[i].type].vendor, 8); @@ -4630,7 +4767,6 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam temp_cdrom[lv2_current_sel].early = settings_get_check(hdlg, IDC_CHECKEARLY); win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); break; - } ignore_change = 0; @@ -4903,7 +5039,7 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa dev = isartc_get_device(d); if (device_is_valid(dev, temp_machine)) { if (d == 0) { - settings_add_string(hdlg, IDC_COMBO_ISARTC, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_ISARTC, win_get_string(IDS_2104)); settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, 0); } else settings_add_string(hdlg, IDC_COMBO_ISARTC, (LPARAM) device_name); @@ -4929,7 +5065,7 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa dev = isamem_get_device(d); if (device_is_valid(dev, temp_machine)) { if (d == 0) { - settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, win_get_string(IDS_2103)); + settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, win_get_string(IDS_2104)); settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, 0); } else settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, (LPARAM) device_name); @@ -5085,7 +5221,7 @@ win_settings_confirm(HWND hdlg) if (win_settings_changed()) { if (confirm_save && !settings_only) - i = settings_msgbox_ex(MBX_QUESTION_OK | MBX_WARNING | MBX_DONTASK, (wchar_t *) IDS_2121, (wchar_t *) IDS_2122, (wchar_t *) IDS_2123, NULL, NULL); + i = settings_msgbox_ex(MBX_QUESTION_OK | MBX_WARNING | MBX_DONTASK, (wchar_t *) IDS_2122, (wchar_t *) IDS_2123, (wchar_t *) IDS_2124, NULL, NULL); else i = 0; diff --git a/src/win/win_snd_gain.c b/src/win/win_snd_gain.c index 6f5e834c5..358942e39 100644 --- a/src/win/win_snd_gain.c +++ b/src/win/win_snd_gain.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handle the sound gain dialog. + * Handle the sound gain dialog. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2018 Miran Grca. */ #define UNICODE #define BITMAP WINDOWS_BITMAP diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c index b4d44087c..184c39d4f 100644 --- a/src/win/win_specify_dim.c +++ b/src/win/win_specify_dim.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Handle the dialog for specifying the dimensions of the main window. + * Handle the dialog for specifying the dimensions of the main window. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2018 Miran Grca. */ #define UNICODE #define BITMAP WINDOWS_BITMAP diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 6178b73ce..5586f9d15 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implement the application's Status Bar. + * Implement the application's Status Bar. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -188,10 +188,10 @@ StatusBarCreateCassetteTip(int part) WCHAR fn[512]; if (strlen(cassette_fname) == 0) - _swprintf(tempTip, plat_get_string(IDS_2148), plat_get_string(IDS_2057)); + _swprintf(tempTip, plat_get_string(IDS_2149), plat_get_string(IDS_2057)); else { mbstoc16s(fn, cassette_fname, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2148), fn); + _swprintf(tempTip, plat_get_string(IDS_2149), fn); } if (sbTips[part] != NULL) { @@ -210,11 +210,11 @@ StatusBarCreateCartridgeTip(int part) int drive = sb_part_meanings[part] & 0xf; if (strlen(cart_fns[drive]) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2150), + _swprintf(tempTip, plat_get_string(IDS_2151), drive + 1, plat_get_string(IDS_2057)); } else { mbstoc16s(fn, cart_fns[drive], sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2150), + _swprintf(tempTip, plat_get_string(IDS_2151), drive + 1, fn); } @@ -238,11 +238,11 @@ StatusBarCreateFloppyTip(int part) mbstoc16s(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); if (strlen(floppyfns[drive]) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2108), + _swprintf(tempTip, plat_get_string(IDS_2109), drive + 1, wtext, plat_get_string(IDS_2057)); } else { mbstoc16s(fn, floppyfns[drive], sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2108), + _swprintf(tempTip, plat_get_string(IDS_2109), drive + 1, wtext, fn); } @@ -333,11 +333,11 @@ StatusBarCreateMOTip(int part) szText = plat_get_string(id); if (strlen(mo_drives[drive].image_path) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2115), + _swprintf(tempTip, plat_get_string(IDS_2116), drive + 1, szText, plat_get_string(IDS_2057)); } else { mbstoc16s(fn, mo_drives[drive].image_path, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2115), + _swprintf(tempTip, plat_get_string(IDS_2116), drive + 1, szText, fn); } @@ -989,13 +989,13 @@ StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst) sb_parts++; SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); SendMessage(hwndSBAR, SB_SETTEXT, 0 | SBT_NOBORDERS, - (LPARAM) plat_get_string(IDS_2117)); + (LPARAM) plat_get_string(IDS_2118)); sb_ready = 1; } void -ui_sb_update_text() +ui_sb_update_text(void) { uint8_t part = 0xff; diff --git a/src/win/win_thread.c b/src/win/win_thread.c index 16b984a9c..97ea3a56c 100644 --- a/src/win/win_thread.c +++ b/src/win/win_thread.c @@ -1,20 +1,20 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Implement threads and mutexes for the Win32 platform. + * Implement threads and mutexes for the Win32 platform. * * * - * Authors: Sarah Walker, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Fred N. van Kempen, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2017-2018 Fred N. van Kempen. */ #define UNICODE #define BITMAP WINDOWS_BITMAP diff --git a/src/win/win_toolbar.c b/src/win/win_toolbar.c index 008be5c9e..fade8d25e 100644 --- a/src/win/win_toolbar.c +++ b/src/win/win_toolbar.c @@ -28,7 +28,7 @@ enum image_index { }; void -ToolBarLoadIcons() +ToolBarLoadIcons(void) { if (!hwndToolbar) return; @@ -72,25 +72,25 @@ ToolBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (idButton) { case IDM_ACTION_PAUSE: if (dopause) - lpttt->lpszText = MAKEINTRESOURCE(IDS_2154); - else lpttt->lpszText = MAKEINTRESOURCE(IDS_2155); + else + lpttt->lpszText = MAKEINTRESOURCE(IDS_2156); break; case IDM_ACTION_RESET_CAD: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2156); - break; - - case IDM_ACTION_CTRL_ALT_ESC: lpttt->lpszText = MAKEINTRESOURCE(IDS_2157); break; - case IDM_ACTION_HRESET: + case IDM_ACTION_CTRL_ALT_ESC: lpttt->lpszText = MAKEINTRESOURCE(IDS_2158); break; + case IDM_ACTION_HRESET: + lpttt->lpszText = MAKEINTRESOURCE(IDS_2159); + break; + case IDM_CONFIG: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2160); + lpttt->lpszText = MAKEINTRESOURCE(IDS_2161); break; } diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 803ed2a80..38d7e161c 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -1,23 +1,23 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * user Interface module for WinAPI on Windows. + * user Interface module for WinAPI on Windows. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2019,2020 GH Cao. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2019-2020 GH Cao. */ #include #define UNICODE @@ -53,8 +53,9 @@ #define TIMER_1SEC 1 /* ID of the one-second timer */ /* Platform Public data, specific. */ -HWND hwndMain = NULL, /* application main window */ - hwndRender = NULL; /* machine render window */ +HWND hwndMain = NULL, /* application main window */ + hwndRender = NULL, /* machine render window */ + hwndRender2 = NULL; /* machine second screen render window */ HMENU menuMain; /* application main menu */ RECT oldclip; /* mouse rect */ int sbar_height = 23; /* statusbar height */ @@ -199,7 +200,7 @@ static int menu_vidapi = -1; static HMENU cur_menu = NULL; static void -show_render_options_menu() +show_render_options_menu(void) { if (vid_api == menu_vidapi) return; @@ -213,7 +214,7 @@ show_render_options_menu() switch (IDM_VID_SDL_SW + vid_api) { case IDM_VID_OPENGL_CORE: cur_menu = LoadMenu(hinstance, VID_GL_SUBMENU); - InsertMenu(GetSubMenu(menuMain, 1), 6, MF_BYPOSITION | MF_STRING | MF_POPUP, (UINT_PTR) cur_menu, plat_get_string(IDS_2144)); + InsertMenu(GetSubMenu(menuMain, 1), 6, MF_BYPOSITION | MF_STRING | MF_POPUP, (UINT_PTR) cur_menu, plat_get_string(IDS_2145)); CheckMenuItem(menuMain, IDM_VID_GL_FPS_BLITTER, video_framerate == -1 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_GL_FPS_25, video_framerate == 25 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_GL_FPS_30, video_framerate == 30 ? MF_CHECKED : MF_UNCHECKED); @@ -252,6 +253,7 @@ ResetAllMenus(void) CheckMenuItem(menuMain, IDM_VID_OVERSCAN, MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_INVERT, MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_VID_MONITORS, MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_SDL_SW, MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_SDL_HW, MF_UNCHECKED); @@ -297,6 +299,9 @@ ResetAllMenus(void) CheckMenuItem(menuMain, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); + if (show_second_monitors == 1) + CheckMenuItem(menuMain, IDM_VID_MONITORS, MF_CHECKED); + if (vid_resize == 1) CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_CHECKED); CheckMenuItem(menuMain, IDM_VID_SDL_SW + vid_api, MF_CHECKED); @@ -494,7 +499,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_ACTION_HRESET: win_notify_dlg_open(); if (confirm_reset) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2112, NULL, (wchar_t *) IDS_2137, (wchar_t *) IDS_2138, NULL); + i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2138, (wchar_t *) IDS_2139, NULL); else i = 0; if ((i % 10) == 0) { @@ -515,7 +520,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_ACTION_EXIT: win_notify_dlg_open(); if (confirm_exit && confirm_exit_cmdl) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2119, (wchar_t *) IDS_2136, NULL); + i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2114, NULL, (wchar_t *) IDS_2120, (wchar_t *) IDS_2137, NULL); else i = 0; if ((i % 10) == 0) { @@ -600,6 +605,11 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) config_save(); break; + case IDM_VID_MONITORS: + show_second_monitors ^= 1; + CheckMenuItem(hmenu, IDM_VID_MONITORS, (show_second_monitors & 1) ? MF_CHECKED : MF_UNCHECKED); + break; + case IDM_VID_RESIZE: vid_resize ^= 1; CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 1) ? MF_CHECKED : MF_UNCHECKED); @@ -696,7 +706,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_VID_GL_SHADER: win_notify_dlg_open(); - if (file_dlg_st(hwnd, IDS_2143, video_shader, NULL, 0) == 0) { + if (file_dlg_st(hwnd, IDS_2144, video_shader, NULL, 0) == 0) { strcpy_s(video_shader, sizeof(video_shader), openfilestring); EnableMenuItem(menuMain, IDM_VID_GL_NOSHADER, strlen(video_shader) > 0 ? MF_ENABLED : MF_DISABLED); } @@ -943,7 +953,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_CLOSE: win_notify_dlg_open(); if (confirm_exit && confirm_exit_cmdl) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2119, (wchar_t *) IDS_2136, NULL); + i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2114, NULL, (wchar_t *) IDS_2120, (wchar_t *) IDS_2137, NULL); else i = 0; if ((i % 10) == 0) { @@ -986,7 +996,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; win_notify_dlg_open(); if (confirm_reset) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2112, NULL, (wchar_t *) IDS_2137, (wchar_t *) IDS_2138, NULL); + i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2138, (wchar_t *) IDS_2139, NULL); else i = 0; if ((i % 10) == 0) { @@ -1012,7 +1022,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } else { win_notify_dlg_open(); if (confirm_exit && confirm_exit_cmdl) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2119, (wchar_t *) IDS_2136, NULL); + i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2114, NULL, (wchar_t *) IDS_2120, (wchar_t *) IDS_2137, NULL); else i = 0; if ((i % 10) == 0) { @@ -1157,7 +1167,7 @@ ui_init(int nCmdShow) int bRet; TASKDIALOGCONFIG tdconfig = { 0 }; TASKDIALOG_BUTTON tdbuttons[] = { - {IDCANCEL, MAKEINTRESOURCE(IDS_2119)} + {IDCANCEL, MAKEINTRESOURCE(IDS_2120)} }; uint32_t helper_lang; @@ -1187,7 +1197,7 @@ ui_init(int nCmdShow) if (settings_only) { if (!pc_init_modules()) { /* Dang, no ROMs found at all! */ - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2120); + tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2121); tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return (6); @@ -1322,7 +1332,7 @@ ui_init(int nCmdShow) ShowWindow(hwnd, nCmdShow); /* Warn the user about unsupported configs. */ - if (cpu_override && ui_msgbox_ex(MBX_WARNING | MBX_QUESTION_OK, (void *) IDS_2145, (void *) IDS_2146, (void *) IDS_2147, (void *) IDS_2119, NULL)) { + if (cpu_override && ui_msgbox_ex(MBX_WARNING | MBX_QUESTION_OK, (void *) IDS_2146, (void *) IDS_2147, (void *) IDS_2148, (void *) IDS_2120, NULL)) { DestroyWindow(hwnd); return (0); } @@ -1336,7 +1346,7 @@ ui_init(int nCmdShow) ridev.dwFlags = RIDEV_NOHOTKEYS; ridev.hwndTarget = NULL; /* current focus window */ if (!RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) { - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2105); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2106); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return (4); } @@ -1345,7 +1355,7 @@ ui_init(int nCmdShow) /* Load the accelerator table */ haccel = LoadAccelerators(hinstance, ACCEL_NAME); if (haccel == NULL) { - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2104); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2105); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return (3); } @@ -1363,7 +1373,7 @@ ui_init(int nCmdShow) /* All done, fire up the actual emulated machine. */ if (!pc_init_modules()) { /* Dang, no ROMs found at all! */ - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2120); + tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2121); tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return (6); @@ -1371,7 +1381,7 @@ ui_init(int nCmdShow) /* Initialize the configured Video API. */ if (!plat_setvid(vid_api)) { - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2089); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2090); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return (5); } diff --git a/vcpkg.json b/vcpkg.json index 0bf171db8..f3f420b33 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "3.8", + "version-string": "3.11", "homepage": "https://86box.net/", "documentation": "http://86box.readthedocs.io/", "license": "GPL-2.0-or-later",